Advertisement
Galebickosikasa

Untitled

Aug 27th, 2020
55
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.22 KB | None | 0 0
  1. #pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math")
  2. #pragma GCC target("sse,sse2,sse3,ssse3,sse4,sse4.1,sse4.2,popcnt,abm,mmx,avx")
  3. // #pragma comment(linker, "/stack:200000000"]
  4.  
  5. #include <iostream>
  6. #include <vector>
  7. #include <cmath>
  8. #include <algorithm>
  9. #include <unordered_set>
  10. #include <unordered_map>
  11. #include <set>
  12. #include <map>
  13. #include <queue>
  14. #include <deque>
  15. #include <bitset>
  16. #include <stack>
  17. #include <random>
  18. #include <fstream>
  19. #include <sstream>
  20. #include <chrono>
  21.  
  22. #define fi first
  23. #define se second
  24. #define pb push_back
  25. #define ll long long
  26. #define ld long double
  27. #define hm unordered_map
  28. #define pii pair<int, int>
  29. #define sz(a) (int)a.size()
  30. #define all(a) a.begin(), a.end()
  31. #define cinv(v) for (auto& x: v) cin >> x
  32. #define fr(i, n) for (int i = 0; i < n; ++i)
  33. #define fl(i, l, n) for (int i = l; i < n; ++i)
  34.  
  35. // #define int ll
  36.  
  37. using namespace std;
  38.  
  39. #ifdef __LOCAL
  40. #define dbg(x) cerr << #x << " : " << x << '\n'
  41. const int maxn = 2e5 + 20;
  42. #else
  43. #define dbg(x)
  44. const int maxn = 2e5 + 20;
  45. #endif
  46.  
  47. //tg: @galebickosikasa
  48.  
  49. ostream& operator << (ostream& out, vector<int>& v) {
  50. for (auto& x: v) out << x << ' ';
  51. return out;
  52. }
  53.  
  54. ostream& operator << (ostream& out, pii& v) {
  55. out << v.fi << ", " << v.se;
  56. return out;
  57. }
  58.  
  59. ostream& operator << (ostream& out, vector<pii>& v) {
  60. for (auto& x: v) out << x << '\n';
  61. return out;
  62. }
  63.  
  64. istream& operator >> (istream& in, pii& a) {
  65. in >> a.fi >> a.se;
  66. return in;
  67. }
  68.  
  69. const ll inf = (ll) 2e9;
  70. const ll kek = 2e18;
  71. const ld pi = asin (1) * 2;
  72. const ld eps = 1e-8;
  73. const ll mod = (ll)1e9 + 7;
  74. const ll ns = 97;
  75. const int maxs = 1e6 + 20;
  76.  
  77. mt19937 rnd(chrono::steady_clock::now().time_since_epoch().count());
  78.  
  79. multiset<int> answers;
  80. int parent[maxn], sz[maxn], colors[maxn], pr[maxn], pos[maxn], order[maxn];
  81. ll dist[maxn];
  82. vector<pii> g[maxn];
  83. int j = 0, ind = 0;
  84.  
  85. void dfs (int v, int p = -1) {
  86. parent[v] = p;
  87. order[j++] = v;
  88. sz[v] = 1;
  89. for (auto& u: g[v]) {
  90. if (u.fi == p) continue;
  91. dist[u.fi] = dist[v] + (ll)u.se;
  92. dfs (u.fi, v);
  93. sz[v] += sz[u.fi];
  94. }
  95. }
  96.  
  97. struct DSU {
  98. vector<int> dsu, size;
  99.  
  100. DSU (int s = maxn) {
  101. dsu = vector<int> (s);
  102. size = vector<int> (s, 1);
  103. fr (i, s) dsu[i] = i;
  104. }
  105.  
  106. int get (int x) {
  107. if (dsu[x] == x) return x;
  108. return dsu[x] = get (dsu[x]);
  109. }
  110.  
  111. bool join (int a, int b) {
  112. int x = get (a), y = get (b);
  113. if (x != y) {
  114. if (size[x] > size[y]) swap (x, y);
  115. dsu[x] = y;
  116. size[y] += size[x];
  117. return 1;
  118. }
  119. return 0;
  120. }
  121. };
  122.  
  123. struct edge {
  124. int a, b, c;
  125.  
  126. bool operator < (const edge& other) const {
  127. return c < other.c;
  128. }
  129. };
  130.  
  131. edge edges[maxn];
  132.  
  133. struct Tree { // типа BST
  134. int left, right, color, mx, mn;
  135. ll value;
  136.  
  137. Tree () {
  138. left = right = -1;
  139. }
  140.  
  141. Tree (ll d, int x) {
  142. left = right = -1;
  143. value = d;
  144. color = mx = mn = x;
  145. }
  146. };
  147.  
  148. Tree mas[maxn * 4];
  149.  
  150. int get_mn (int t) {
  151. if (t == -1) return inf;
  152. return mas[t].mn;
  153. }
  154.  
  155. int get_mx (int t) {
  156. if (t == -1) return -inf;
  157. return mas[t].mx;
  158. }
  159.  
  160. ll get_val (int t) {
  161. if (t == -1) return -1;
  162. return mas[t].value;
  163. }
  164.  
  165. void render (int t) {
  166. if (t == -1) return;
  167. mas[t].mx = max (mas[t].color, max (get_mx (mas[t].left), get_mx (mas[t].right)));
  168. mas[t].mn = min (mas[t].color, min (get_mn (mas[t].left), get_mn (mas[t].right)));
  169. }
  170.  
  171. int leftest (int t) {
  172. if (mas[t].left == -1) return t;
  173. return leftest (mas[t].left);
  174. }
  175.  
  176. int erase (int t, int d, int x) {
  177. if (t == -1) return t;
  178. if (mas[t].value == d && mas[t].color == x) {
  179. if (mas[t].left != -1 && mas[t].right != -1) {
  180. int a = leftest (mas[t].right);
  181. mas[t].value = mas[a].value;
  182. mas[t].color = mas[a].color;
  183. mas[t].right = erase (mas[t].right, mas[a].value, mas[a].color);
  184. } else if (mas[t].left != -1) {
  185. return mas[t].left;
  186. } else if (mas[t].right != -1) {
  187. return mas[t].right;
  188. } return -1;
  189. }
  190. if (mas[t].value > d || mas[t].value == d && mas[t].color > x) {
  191. mas[t].left = erase (mas[t].left, d, x);
  192. } else {
  193. mas[t].right = erase (mas[t].right, d, x);
  194. }
  195. render (t);
  196. return t;
  197. }
  198.  
  199. int add (int t, int a) {
  200. if (t == -1) return a;
  201. if (mas[t].value > mas[a].value) mas[t].left = add (mas[t].left, a);
  202. else mas[t].right = add (mas[t].right, a);
  203. render (t);
  204. return t;
  205. }
  206.  
  207. int add (int t, ll d, int x) {
  208. mas[ind++] = Tree (d, x);
  209. return add (t, ind - 1);
  210. }
  211.  
  212. // void dfs (Tree* t) {
  213. // if (t == nullptr) return;
  214. // dfs (t->left);
  215. // dbg (t->value);
  216. // dbg (t->color);
  217. // dfs (t->right);
  218. // }
  219.  
  220. ll down (int t, int new_color) {
  221. if (t == -1 || (mas[t].mn == new_color && mas[t].mx == new_color)) return kek;
  222. ll ans = kek;
  223. // dbg (t->value);
  224. // dfs (t);
  225. // dbg ("exit");
  226. // dbg (get_val (t->left));
  227. // dbg (get_val (t->right));
  228. if (mas[t].color != new_color) ans = mas[t].value;
  229. if (get_mn (mas[t].left) == inf || (get_mn (mas[t].left) == new_color && get_mx (mas[t].left) == new_color)) {
  230. ans = min (ans, down (mas[t].right, new_color));
  231. // dbg ("right");
  232. // dbg (ans);
  233. return ans;
  234. }
  235. ans = min (ans, down (mas[t].left, new_color));
  236. // dbg ("left");
  237. // dbg (ans);
  238. return ans;
  239. }
  240.  
  241. struct ST {
  242. int t[4 * maxn];
  243. int size = 0, capacity;
  244.  
  245. ST (int s = maxn) {
  246. while ((1<<size) < s) ++size;
  247. ++size;
  248. size = (1<<size);
  249. capacity = (size>>1);
  250. vector<vector<pii>> tmp (size);
  251. fr (i, size) t[i] = -1;
  252. fr (i, j) {
  253. tmp[i + capacity].pb ({dist[order[i]], colors[order[i]]});
  254. t[i + capacity] = add (t[i + capacity], dist[order[i]], colors[order[i]]);
  255. }
  256. for (int i = capacity - 1; i > 0; --i) {
  257. tmp[i] = vector<pii> (sz (tmp[i * 2]) + sz (tmp[i * 2 + 1]));
  258. int j = 0;
  259. for (auto& x: tmp[i * 2]) tmp[i][j++] = x;
  260. for (auto& x: tmp[i * 2 + 1]) tmp[i][j++] = x;
  261. for (auto& x: tmp[i]) t[i] = add (t[i], x.fi, x.se);
  262. }
  263. }
  264.  
  265. ll upd (int cur, int left, int right, int l, int r, int new_color) {
  266. if (cur >= size) return kek;
  267. if (left > r || right < l) return kek;
  268. if (l <= left && r >= right) {
  269. // dbg ("open");
  270. // dbg (cur);
  271. return down (t[cur], new_color);
  272. }
  273. return min (upd (cur * 2, left, (left + right) / 2, l, r, new_color), upd (cur * 2 + 1, (left + right) / 2 + 1, right, l, r, new_color));
  274. }
  275.  
  276. ll upd (int l, int r, int new_color) {
  277. return upd (1, 0, capacity - 1, l, r, new_color);
  278. }
  279.  
  280. void upd (int v, int new_color) {
  281. if (v < 0) {
  282. v *= -1;
  283. ll x = upd (pos[v] + 1, pos[v] + sz[v] - 1, new_color) - dist[v];
  284. int p = pr[v];
  285. if (p < inf) {
  286. auto it = answers.find (p);
  287. if (it != answers.end ()) answers.erase (it);
  288. }
  289. if (x + dist[v] < inf) answers.insert (x), pr[v] = x;
  290. return;
  291. }
  292.  
  293. if (sz[v] <= 1) {
  294. int u = pos[v] + capacity;
  295. int p = colors[v];
  296. while (u) {
  297. t[u] = erase (t[u], dist[v], p);
  298. t[u] = add (t[u], dist[v], new_color);
  299. u /= 2;
  300. }
  301. return;
  302. }
  303. int u = pos[v] + capacity;
  304. // dbg (u);
  305. int p = colors[v];
  306. while (u) {
  307. // dbg ("here");
  308. // dfs (t[u]);
  309. t[u] = erase (t[u], dist[v], p);
  310. // dbg (dist[v]);
  311. // dbg (p);
  312. // dbg ("cont");
  313. // dfs (t[u]);
  314. t[u] = add (t[u], dist[v], new_color);
  315. // dbg ("end");
  316. // dfs (t[u]);
  317. u /= 2;
  318. }
  319. ll x = upd (pos[v] + 1, pos[v] + sz[v] - 1, new_color) - dist[v];
  320. // dbg (v);
  321. // dbg (x);
  322. p = pr[v];
  323. // dbg (p);
  324. if (p < inf) {
  325. auto it = answers.find (p);
  326. if (it != answers.end ()) answers.erase (it);
  327. }
  328. if (x + dist[v] < inf) answers.insert (x), pr[v] = x;
  329. }
  330. };
  331.  
  332. signed main () {
  333. ios_base::sync_with_stdio(false);
  334. cin.tie(nullptr);
  335. cout.tie(nullptr);
  336. int n, m, d, q;
  337. cin >> n >> m >> d >> q;
  338. fr (i, m) {
  339. int a, b, c;
  340. cin >> a >> b >> c;
  341. edges[i] = {a, b, c};
  342. }
  343. sort (edges, edges + m);
  344. DSU dsu (n + 1);
  345. fr (i, m) {
  346. auto& e = edges[i];
  347. if (dsu.join (e.a, e.b)) {
  348. g[e.a].pb ({e.b, e.c}), g[e.b].pb ({e.a, e.c});
  349. }
  350. }
  351. dfs (1);
  352. fr (i, j) {
  353. pos[order[i]] = i;
  354. }
  355. fr (i, n) {
  356. int x;
  357. cin >> x;
  358. colors[i + 1] = x;
  359. }
  360. for (auto& x: pr) x = inf;
  361. ST goo (n + 1);
  362. fr (i, n) goo.upd (i + 1, colors[i + 1]);
  363. fr (i, q) {
  364. int v, x;
  365. cin >> v >> x;
  366. goo.upd (v, x);
  367. colors[v] = x;
  368. if (parent[v] != -1) goo.upd (-parent[v], colors[parent[v]]);
  369. cout << *answers.begin () << '\n';
  370. }
  371.  
  372.  
  373.  
  374.  
  375.  
  376.  
  377.  
  378. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement