From 19e0a43a994a7adc37cf54ff4a6b758fd707c1d8 Mon Sep 17 00:00:00 2001
From: Shuhao Zhang <594422141@qq.com>
Date: Sat, 17 Aug 2019 16:42:53 +0800
Subject: [PATCH] fold the code
---
docs/misc/mo-algo.md | 824 ++++++++++++++++++++++++++-------------------------
1 file changed, 415 insertions(+), 409 deletions(-)
diff --git a/docs/misc/mo-algo.md b/docs/misc/mo-algo.md
index 3d0ab964..65483690 100644
--- a/docs/misc/mo-algo.md
+++ b/docs/misc/mo-algo.md
@@ -116,50 +116,54 @@ $$
ç®æ³æ»å¤æåº¦ï¼ $O(n\sqrt{n} )$
-ä¸é¢ç代ç ä¸ `mot` 表示çæ¡çåæ¯ (mother)ï¼ `sub` 表示ååï¼ `sqn` 表示åç大å°ï¼ $\sqrt{n}$ ï¼ `arr` æ¯è¾å
¥çæ°ç»ï¼ `node` æ¯åå¨è¯¢é®çç»æä½ï¼ `tab` æ¯è¯¢é®åºåï¼æåºåçï¼ï¼ `col` åä¸æè¿°ã注æï¼ä¸é¢ä»£ç ä¸ç移å¨åºé´ç 4 个 for 循ç¯çä½ç½®å¾å
³é®ï¼ä¸è½æ¹åå®ä»¬ä¹é´çä½ç½®å
³ç³»ï¼ä¸ç¶ä¼ WAï¼å 为æé£ä¸ª `++l` å `--r` ï¼ã代ç ï¼
-
-```cpp
-#include
-#define bi(a) ((a - 1) / sqn + 1)
-using namespace std;
-typedef long long LL;
-template
-void read(tp& dig) {
- char c = getchar();
- dig = 0;
- while (!isdigit(c)) c = getchar();
- while (isdigit(c)) dig = dig * 10 + c - '0', c = getchar();
-}
-struct node {
- LL l, r, i;
-};
-LL n, m, sqn, arr[50005], l, r, ans, col[50005], sub[50005], mot[50005];
-vector tab;
-bool cmp(node a, node b) {
- if (bi(a.l) == bi(b.l)) return a.r < b.r;
- return a.l < b.l;
-}
-LL gcd(LL a, LL b) { return !b ? a : gcd(b, a % b); }
-int main() {
- read(n), read(m), sqn = sqrt(n);
- for (LL i = 1; i <= n; i++) read(arr[i]);
- for (LL i = 1, a, b; i <= m; i++)
- read(a), read(b), tab.push_back((node){a, b, i});
- sort(tab.begin(), tab.end(), cmp), l = r = tab[0].l, col[arr[l]]++;
- for (LL i = 0, gcdnum; i < tab.size(); i++) {
- for (; l < tab[i].l; l++) col[arr[l]]--, ans -= col[arr[l]];
- for (--l; l >= tab[i].l; l--) ans += col[arr[l]], col[arr[l]]++;
- for (; r > tab[i].r; r--) col[arr[r]]--, ans -= col[arr[r]];
- for (++r; r <= tab[i].r; r++) ans += col[arr[r]], col[arr[r]]++;
- sub[tab[i].i] = ans, l = tab[i].l, r = tab[i].r;
- mot[tab[i].i] = ((r - l) * (r - l + 1)) >> 1;
- }
- for (LL i = 1, gcdn; i <= m; i++)
- gcdn = gcd(sub[i], mot[i]),
- printf("%lld/%lld\n", sub[i] / gcdn, mot[i] / gcdn);
- return 0;
-}
-```
+ä¸é¢ç代ç ä¸ `mot` 表示çæ¡çåæ¯ (mother)ï¼ `sub` 表示ååï¼ `sqn` 表示åç大å°ï¼ $\sqrt{n}$ ï¼ `arr` æ¯è¾å
¥çæ°ç»ï¼ `node` æ¯åå¨è¯¢é®çç»æä½ï¼ `tab` æ¯è¯¢é®åºåï¼æåºåçï¼ï¼ `col` åä¸æè¿°ã
+
+**注æï¼ä¸é¢ä»£ç ä¸ç移å¨åºé´ç 4 个 for 循ç¯çä½ç½®å¾å
³é®ï¼ä¸è½æ¹åå®ä»¬ä¹é´çä½ç½®å
³ç³»ï¼ä¸ç¶ä¼ WAï¼å 为æé£ä¸ª `++l` å `--r` ï¼ã**
+
+??? åè代ç
+
+ ```cpp
+ #include
+ #define bi(a) ((a - 1) / sqn + 1)
+ using namespace std;
+ typedef long long LL;
+ template
+ void read(tp& dig) {
+ char c = getchar();
+ dig = 0;
+ while (!isdigit(c)) c = getchar();
+ while (isdigit(c)) dig = dig * 10 + c - '0', c = getchar();
+ }
+ struct node {
+ LL l, r, i;
+ };
+ LL n, m, sqn, arr[50005], l, r, ans, col[50005], sub[50005], mot[50005];
+ vector tab;
+ bool cmp(node a, node b) {
+ if (bi(a.l) == bi(b.l)) return a.r < b.r;
+ return a.l < b.l;
+ }
+ LL gcd(LL a, LL b) { return !b ? a : gcd(b, a % b); }
+ int main() {
+ read(n), read(m), sqn = sqrt(n);
+ for (LL i = 1; i <= n; i++) read(arr[i]);
+ for (LL i = 1, a, b; i <= m; i++)
+ read(a), read(b), tab.push_back((node){a, b, i});
+ sort(tab.begin(), tab.end(), cmp), l = r = tab[0].l, col[arr[l]]++;
+ for (LL i = 0, gcdnum; i < tab.size(); i++) {
+ for (; l < tab[i].l; l++) col[arr[l]]--, ans -= col[arr[l]];
+ for (--l; l >= tab[i].l; l--) ans += col[arr[l]], col[arr[l]]++;
+ for (; r > tab[i].r; r--) col[arr[r]]--, ans -= col[arr[r]];
+ for (++r; r <= tab[i].r; r++) ans += col[arr[r]], col[arr[r]]++;
+ sub[tab[i].i] = ans, l = tab[i].l, r = tab[i].r;
+ mot[tab[i].i] = ((r - l) * (r - l + 1)) >> 1;
+ }
+ for (LL i = 1, gcdn; i <= m; i++)
+ gcdn = gcd(sub[i], mot[i]),
+ printf("%lld/%lld\n", sub[i] / gcdn, mot[i] / gcdn);
+ return 0;
+ }
+ ```
## æ®éè«éçä¼å
@@ -173,9 +177,9 @@ int main() {
4 100
```
-æå¨æ¨¡æä¸ä¸å¯ä»¥åç°ï¼r æéç移å¨æ¬¡æ°å¤§æ¦ä¸º 300 次ï¼æ们å¤çå®ç¬¬ä¸ä¸ªåä¹åï¼ $l = 2, r = 100$ ï¼æ¤æ¶åªéè¦ç§»å¨ä¸¤æ¬¡ l æéå°±å¯ä»¥å¾å°ç¬¬å个询é®ççæ¡ï¼ä½æ¯æ们å´å° r æé移å¨å° 1 æ¥è·å第ä¸ä¸ªè¯¢é®ççæ¡ï¼å移å¨å° 100 è·å第å个询é®ççæ¡ï¼è¿æ ·å¤äºä¹åå 次çæé移å¨ãæ们æä¹ä¼åè¿ä¸ªå°æ¹å¢ï¼è¿éæ们就è¦ç¨å°å¥å¶åæåº
+æå¨æ¨¡æä¸ä¸å¯ä»¥åç°ï¼r æéç移å¨æ¬¡æ°å¤§æ¦ä¸º 300 次ï¼æ们å¤çå®ç¬¬ä¸ä¸ªåä¹åï¼ $l = 2, r = 100$ ï¼æ¤æ¶åªéè¦ç§»å¨ä¸¤æ¬¡ l æéå°±å¯ä»¥å¾å°ç¬¬å个询é®ççæ¡ï¼ä½æ¯æ们å´å° r æé移å¨å° 1 æ¥è·å第ä¸ä¸ªè¯¢é®ççæ¡ï¼å移å¨å° 100 è·å第å个询é®ççæ¡ï¼è¿æ ·å¤äºä¹åå 次çæé移å¨ãæ们æä¹ä¼åè¿ä¸ªå°æ¹å¢ï¼è¿éæ们就è¦ç¨å°å¥å¶åæåºã
-ä»ä¹æ¯å¥å¶åæåºï¼å¥å¶åæåºå³å¯¹äºå±äºå¥æ°åç询é®ï¼r æä»å°å°å¤§æåºï¼å¯¹äºå±äºå¶æ°åçæåºï¼r ä»å¤§å°å°æåºï¼è¿æ ·æ们ç r æéå¨å¤çå®è¿ä¸ªå¥æ°åçé®é¢åï¼å°å¨è¿åçéä¸å¤çå¶æ°åçé®é¢ï¼åå n 移å¨å¤çä¸ä¸ä¸ªå¥æ°åçé®é¢ï¼ä¼åäº r æéç移å¨æ¬¡æ°ï¼ä¸è¬æ
åµä¸ï¼è¿ç§ä¼åè½è®©ç¨åºå¿« 30% å·¦å³
+ä»ä¹æ¯å¥å¶åæåºï¼å¥å¶åæåºå³å¯¹äºå±äºå¥æ°åç询é®ï¼r æä»å°å°å¤§æåºï¼å¯¹äºå±äºå¶æ°åçæåºï¼r ä»å¤§å°å°æåºï¼è¿æ ·æ们ç r æéå¨å¤çå®è¿ä¸ªå¥æ°åçé®é¢åï¼å°å¨è¿åçéä¸å¤çå¶æ°åçé®é¢ï¼åå n 移å¨å¤çä¸ä¸ä¸ªå¥æ°åçé®é¢ï¼ä¼åäº r æéç移å¨æ¬¡æ°ï¼ä¸è¬æ
åµä¸ï¼è¿ç§ä¼åè½è®©ç¨åºå¿« 30% å·¦å³ã
æåºä»£ç ï¼
@@ -252,12 +256,12 @@ struct node {
### ä¾é¢
-[æ°é¢è² BZOJ - 2120](https://www.lydsy.com/JudgeOnline/problem.php?id=2120)
-
-é¢ç®å¤§æï¼ç»ä½ ä¸ä¸ªåºåï¼M 个æä½ï¼æ两ç§æä½ï¼
+!!! [æ°é¢è² BZOJ - 2120](https://www.lydsy.com/JudgeOnline/problem.php?id=2120)
-1. ä¿®æ¹åºåä¸æä¸ä½çæ°å
-2. 询é®åºé´ $[l,r]$ ä¸æ°åçç§ç±»æ°ï¼å¤ä¸ªç¸åçæ°ååªç®ä¸ä¸ªï¼
+ é¢ç®å¤§æï¼ç»ä½ ä¸ä¸ªåºåï¼M 个æä½ï¼æ两ç§æä½ï¼
+
+ 1. ä¿®æ¹åºåä¸æä¸ä½çæ°å
+ 2. 询é®åºé´ $[l,r]$ ä¸æ°åçç§ç±»æ°ï¼å¤ä¸ªç¸åçæ°ååªç®ä¸ä¸ªï¼
æ们ä¸é¾åç°ï¼å¦æä¸å¸¦æä½ 1ï¼ä¿®æ¹ï¼çè¯ï¼æ们就è½è½»æ¾ç¨æ®éè«é解å³ã
@@ -280,71 +284,71 @@ struct node {
å æ¤è¿éé¢å°±è¿æ ·ç¨å¸¦ä¿®æ¹è«éè½»æ¾è§£å³å¦ï¼
-代ç ï¼
-
-```cpp
-#include
-#define SZ (10005)
-using namespace std;
-template
-inline void IN(_Tp& dig) {
- char c;
- dig = 0;
- while (c = getchar(), !isdigit(c))
- ;
- while (isdigit(c)) dig = dig * 10 + c - '0', c = getchar();
-}
-int n, m, sqn, c[SZ], ct[SZ], c1, c2, mem[SZ][3], ans, tot[1000005], nal[SZ];
-struct query {
- int l, r, i, c;
- bool operator<(const query another) const {
- if (l / sqn == another.l / sqn) {
- if (r / sqn == another.r / sqn) return i < another.i;
- return r < another.r;
+??? åè代ç
+
+ ```cpp
+ #include
+ #define SZ (10005)
+ using namespace std;
+ template
+ inline void IN(_Tp& dig) {
+ char c;
+ dig = 0;
+ while (c = getchar(), !isdigit(c))
+ ;
+ while (isdigit(c)) dig = dig * 10 + c - '0', c = getchar();
}
- return l < another.l;
- }
-} Q[SZ];
-void add(int a) {
- if (!tot[a]) ans++;
- tot[a]++;
-}
-void del(int a) {
- tot[a]--;
- if (!tot[a]) ans--;
-}
-char opt[10];
-int main() {
- IN(n), IN(m), sqn = pow(n, (double)2 / (double)3);
- for (int i = 1; i <= n; i++) IN(c[i]), ct[i] = c[i];
- for (int i = 1, a, b; i <= m; i++)
- if (scanf("%s", opt), IN(a), IN(b), opt[0] == 'Q')
- Q[c1].l = a, Q[c1].r = b, Q[c1].i = c1, Q[c1].c = c2, c1++;
- else
- mem[c2][0] = a, mem[c2][1] = ct[a], mem[c2][2] = ct[a] = b, c2++;
- sort(Q, Q + c1), add(c[1]);
- int l = 1, r = 1, lst = 0;
- for (int i = 0; i < c1; i++) {
- for (; lst < Q[i].c; lst++) {
- if (l <= mem[lst][0] && mem[lst][0] <= r)
- del(mem[lst][1]), add(mem[lst][2]);
- c[mem[lst][0]] = mem[lst][2];
+ int n, m, sqn, c[SZ], ct[SZ], c1, c2, mem[SZ][3], ans, tot[1000005], nal[SZ];
+ struct query {
+ int l, r, i, c;
+ bool operator<(const query another) const {
+ if (l / sqn == another.l / sqn) {
+ if (r / sqn == another.r / sqn) return i < another.i;
+ return r < another.r;
+ }
+ return l < another.l;
+ }
+ } Q[SZ];
+ void add(int a) {
+ if (!tot[a]) ans++;
+ tot[a]++;
}
- for (; lst > Q[i].c; lst--) {
- if (l <= mem[lst - 1][0] && mem[lst - 1][0] <= r)
- del(mem[lst - 1][2]), add(mem[lst - 1][1]);
- c[mem[lst - 1][0]] = mem[lst - 1][1];
+ void del(int a) {
+ tot[a]--;
+ if (!tot[a]) ans--;
}
- for (++r; r <= Q[i].r; r++) add(c[r]);
- for (--r; r > Q[i].r; r--) del(c[r]);
- for (--l; l >= Q[i].l; l--) add(c[l]);
- for (++l; l < Q[i].l; l++) del(c[l]);
- nal[Q[i].i] = ans;
- }
- for (int i = 0; i < c1; i++) printf("%d\n", nal[i]);
- return 0;
-}
-```
+ char opt[10];
+ int main() {
+ IN(n), IN(m), sqn = pow(n, (double)2 / (double)3);
+ for (int i = 1; i <= n; i++) IN(c[i]), ct[i] = c[i];
+ for (int i = 1, a, b; i <= m; i++)
+ if (scanf("%s", opt), IN(a), IN(b), opt[0] == 'Q')
+ Q[c1].l = a, Q[c1].r = b, Q[c1].i = c1, Q[c1].c = c2, c1++;
+ else
+ mem[c2][0] = a, mem[c2][1] = ct[a], mem[c2][2] = ct[a] = b, c2++;
+ sort(Q, Q + c1), add(c[1]);
+ int l = 1, r = 1, lst = 0;
+ for (int i = 0; i < c1; i++) {
+ for (; lst < Q[i].c; lst++) {
+ if (l <= mem[lst][0] && mem[lst][0] <= r)
+ del(mem[lst][1]), add(mem[lst][2]);
+ c[mem[lst][0]] = mem[lst][2];
+ }
+ for (; lst > Q[i].c; lst--) {
+ if (l <= mem[lst - 1][0] && mem[lst - 1][0] <= r)
+ del(mem[lst - 1][2]), add(mem[lst - 1][1]);
+ c[mem[lst - 1][0]] = mem[lst - 1][1];
+ }
+ for (++r; r <= Q[i].r; r++) add(c[r]);
+ for (--r; r > Q[i].r; r--) del(c[r]);
+ for (--l; l >= Q[i].l; l--) add(c[l]);
+ for (++l; l < Q[i].l; l++) del(c[l]);
+ nal[Q[i].i] = ans;
+ }
+ for (int i = 0; i < c1; i++) printf("%d\n", nal[i]);
+ return 0;
+ }
+ ```
## æ ä¸è«é
@@ -391,173 +395,173 @@ dfs ä¸æ£µæ ï¼ç¶åå¦æ dfs å° x ç¹ï¼å°± push_back(x),dfs å® x ç¹ï¼
ç¶åå 为æå
å«çåºé´å
å¯è½æ²¡æ LCAï¼å¯¹äºæ²¡æçæ
åµè¦å°å¤ä½çè´¡ç®å é¤ï¼ç¶åå°±å®äºäº
-codeï¼
-
-```cpp
-#include
-#include
-#include
-#include
-
-#define DEBUG printf("line:%d func:%s\n", __LINE__, __FUNCTION__);
-
-using namespace std;
-
-const int maxn = 200010;
-
-int f[maxn], g[maxn], id[maxn], head[maxn], cnt, last[maxn], dep[maxn],
- fa[maxn][22], v[maxn], w[maxn];
-int block, index, n, m, q;
-int pos[maxn], col[maxn], app[maxn];
-bool vis[maxn];
-long long ans[maxn], cur;
-
-struct edge {
- int to, nxt;
-} e[maxn];
-int cnt1 = 0, cnt2 = 0; // æ¶é´æ³
-
-struct query {
- int l, r, t, id;
- bool operator<(const query &b) const {
- return (pos[l] < pos[b.l]) || (pos[l] == pos[b.l] && pos[r] < pos[b.r]) ||
- (pos[l] == pos[b.l] && pos[r] == pos[b.r] && t < b.t);
- }
-} a[maxn], b[maxn];
-
-inline void addedge(int x, int y) {
- e[++cnt] = (edge){y, head[x]};
- head[x] = cnt;
-}
-
-void dfs(int x) {
- id[f[x] = ++index] = x;
- for (int i = head[x]; i; i = e[i].nxt) {
- if (e[i].to != fa[x][0]) {
- fa[e[i].to][0] = x;
- dep[e[i].to] = dep[x] + 1;
- dfs(e[i].to);
- }
- }
- id[g[x] = ++index] = x; // æ¬å·åº
-}
-
-inline void swap(int &x, int &y) {
- int t;
- t = x;
- x = y;
- y = t;
-}
-
-inline int lca(int x, int y) {
- if (dep[x] < dep[y]) swap(x, y);
- if (dep[x] != dep[y]) {
- int dis = dep[x] - dep[y];
- for (int i = 20; i >= 0; i--)
- if (dis >= (1 << i)) dis -= 1 << i, x = fa[x][i];
- } // ç¬å°åä¸é«åº¦
- if (x == y) return x;
- for (int i = 20; i >= 0; i--) {
- if (fa[x][i] != fa[y][i]) x = fa[x][i], y = fa[y][i];
- }
- return fa[x][0];
-}
-
-inline void add(int x) {
- if (vis[x])
- cur -= (long long)v[col[x]] * w[app[col[x]]--];
- else
- cur += (long long)v[col[x]] * w[++app[col[x]]];
- vis[x] ^= 1;
-}
-
-inline void modify(int x, int t) {
- if (vis[x]) {
- add(x);
- col[x] = t;
- add(x);
- } else
- col[x] = t;
-} // å¨æ¶é´ç»´ä¸ç§»å¨
-
-int main() {
- scanf("%d%d%d", &n, &m, &q);
- for (int i = 1; i <= m; i++) scanf("%d", &v[i]);
- for (int i = 1; i <= n; i++) scanf("%d", &w[i]);
- for (int i = 1; i < n; i++) {
- int x, y;
- scanf("%d%d", &x, &y);
- addedge(x, y);
- addedge(y, x);
- }
- for (int i = 1; i <= n; i++) {
- scanf("%d", &last[i]);
- col[i] = last[i];
- }
- dfs(1);
- for (int j = 1; j <= 20; j++)
- for (int i = 1; i <= n; i++)
- fa[i][j] = fa[fa[i][j - 1]][j - 1]; // é¢å¤çç¥å
- int block = pow(index, 2.0 / 3);
- for (int i = 1; i <= index; i++) {
- pos[i] = (i - 1) / block;
- }
- while (q--) {
- int opt, x, y;
- scanf("%d%d%d", &opt, &x, &y);
- if (opt == 0) {
- b[++cnt2].l = x;
- b[cnt2].r = last[x];
- last[x] = b[cnt2].t = y;
- } else {
- if (f[x] > f[y]) swap(x, y);
- a[++cnt1] = (query){lca(x, y) == x ? f[x] : g[x], f[y], cnt2, cnt1};
- }
- }
- sort(a + 1, a + cnt1 + 1);
- int L, R, T; // æéåæ
- L = R = 0;
- T = 1;
- for (int i = 1; i <= cnt1; i++) {
- while (T <= a[i].t) {
- modify(b[T].l, b[T].t);
- T++;
+??? åè代ç
+
+ ```cpp
+ #include
+ #include
+ #include
+ #include
+
+ #define DEBUG printf("line:%d func:%s\n", __LINE__, __FUNCTION__);
+
+ using namespace std;
+
+ const int maxn = 200010;
+
+ int f[maxn], g[maxn], id[maxn], head[maxn], cnt, last[maxn], dep[maxn],
+ fa[maxn][22], v[maxn], w[maxn];
+ int block, index, n, m, q;
+ int pos[maxn], col[maxn], app[maxn];
+ bool vis[maxn];
+ long long ans[maxn], cur;
+
+ struct edge {
+ int to, nxt;
+ } e[maxn];
+ int cnt1 = 0, cnt2 = 0; // æ¶é´æ³
+
+ struct query {
+ int l, r, t, id;
+ bool operator<(const query &b) const {
+ return (pos[l] < pos[b.l]) || (pos[l] == pos[b.l] && pos[r] < pos[b.r]) ||
+ (pos[l] == pos[b.l] && pos[r] == pos[b.r] && t < b.t);
+ }
+ } a[maxn], b[maxn];
+
+ inline void addedge(int x, int y) {
+ e[++cnt] = (edge){y, head[x]};
+ head[x] = cnt;
}
- while (T > a[i].t) {
- modify(b[T].l, b[T].r);
- T--;
+
+ void dfs(int x) {
+ id[f[x] = ++index] = x;
+ for (int i = head[x]; i; i = e[i].nxt) {
+ if (e[i].to != fa[x][0]) {
+ fa[e[i].to][0] = x;
+ dep[e[i].to] = dep[x] + 1;
+ dfs(e[i].to);
+ }
+ }
+ id[g[x] = ++index] = x; // æ¬å·åº
}
- while (L > a[i].l) {
- L--;
- add(id[L]);
+
+ inline void swap(int &x, int &y) {
+ int t;
+ t = x;
+ x = y;
+ y = t;
}
- while (L < a[i].l) {
- add(id[L]);
- L++;
+
+ inline int lca(int x, int y) {
+ if (dep[x] < dep[y]) swap(x, y);
+ if (dep[x] != dep[y]) {
+ int dis = dep[x] - dep[y];
+ for (int i = 20; i >= 0; i--)
+ if (dis >= (1 << i)) dis -= 1 << i, x = fa[x][i];
+ } // ç¬å°åä¸é«åº¦
+ if (x == y) return x;
+ for (int i = 20; i >= 0; i--) {
+ if (fa[x][i] != fa[y][i]) x = fa[x][i], y = fa[y][i];
+ }
+ return fa[x][0];
}
- while (R > a[i].r) {
- add(id[R]);
- R--;
+
+ inline void add(int x) {
+ if (vis[x])
+ cur -= (long long)v[col[x]] * w[app[col[x]]--];
+ else
+ cur += (long long)v[col[x]] * w[++app[col[x]]];
+ vis[x] ^= 1;
}
- while (R < a[i].r) {
- R++;
- add(id[R]);
+
+ inline void modify(int x, int t) {
+ if (vis[x]) {
+ add(x);
+ col[x] = t;
+ add(x);
+ } else
+ col[x] = t;
+ } // å¨æ¶é´ç»´ä¸ç§»å¨
+
+ int main() {
+ scanf("%d%d%d", &n, &m, &q);
+ for (int i = 1; i <= m; i++) scanf("%d", &v[i]);
+ for (int i = 1; i <= n; i++) scanf("%d", &w[i]);
+ for (int i = 1; i < n; i++) {
+ int x, y;
+ scanf("%d%d", &x, &y);
+ addedge(x, y);
+ addedge(y, x);
+ }
+ for (int i = 1; i <= n; i++) {
+ scanf("%d", &last[i]);
+ col[i] = last[i];
+ }
+ dfs(1);
+ for (int j = 1; j <= 20; j++)
+ for (int i = 1; i <= n; i++)
+ fa[i][j] = fa[fa[i][j - 1]][j - 1]; // é¢å¤çç¥å
+ int block = pow(index, 2.0 / 3);
+ for (int i = 1; i <= index; i++) {
+ pos[i] = (i - 1) / block;
+ }
+ while (q--) {
+ int opt, x, y;
+ scanf("%d%d%d", &opt, &x, &y);
+ if (opt == 0) {
+ b[++cnt2].l = x;
+ b[cnt2].r = last[x];
+ last[x] = b[cnt2].t = y;
+ } else {
+ if (f[x] > f[y]) swap(x, y);
+ a[++cnt1] = (query){lca(x, y) == x ? f[x] : g[x], f[y], cnt2, cnt1};
+ }
+ }
+ sort(a + 1, a + cnt1 + 1);
+ int L, R, T; // æéåæ
+ L = R = 0;
+ T = 1;
+ for (int i = 1; i <= cnt1; i++) {
+ while (T <= a[i].t) {
+ modify(b[T].l, b[T].t);
+ T++;
+ }
+ while (T > a[i].t) {
+ modify(b[T].l, b[T].r);
+ T--;
+ }
+ while (L > a[i].l) {
+ L--;
+ add(id[L]);
+ }
+ while (L < a[i].l) {
+ add(id[L]);
+ L++;
+ }
+ while (R > a[i].r) {
+ add(id[R]);
+ R--;
+ }
+ while (R < a[i].r) {
+ R++;
+ add(id[R]);
+ }
+ int x = id[L], y = id[R];
+ int llca = lca(x, y);
+ if (x != llca && y != llca) {
+ add(llca);
+ ans[a[i].id] = cur;
+ add(llca);
+ } else
+ ans[a[i].id] = cur;
+ }
+ for (int i = 1; i <= cnt1; i++) {
+ printf("%lld\n", ans[i]);
+ }
+ return 0;
}
- int x = id[L], y = id[R];
- int llca = lca(x, y);
- if (x != llca && y != llca) {
- add(llca);
- ans[a[i].id] = cur;
- add(llca);
- } else
- ans[a[i].id] = cur;
- }
- for (int i = 1; i <= cnt1; i++) {
- printf("%lld\n", ans[i]);
- }
- return 0;
-}
-```
+ ```
## ç·æ ä¸è«é
@@ -609,7 +613,7 @@ void move(int x, int y) {
}
```
-对äºæ± LCAï¼æ们å¯ä»¥ç¨æ åï¼ç¶åæ们就å¯ä»¥æååçæ¥éª¤æ¾å°æ åç第ä¸æ¬¡ dfs éé¢ï¼æ¶é´æ³ä¹å¯ä»¥ç´æ¥ç¨ç¬¬äºæ¬¡ dfs ç dfs åº~~ï¼å¦æä½ ç¨ tarjan å°±å½æ没说ï¼~~
+对äºæ± LCAï¼æ们å¯ä»¥ç¨æ åï¼ç¶åæ们就å¯ä»¥æååçæ¥éª¤æ¾å°æ åç第ä¸æ¬¡ dfs éé¢ï¼æ¶é´æ³ä¹å¯ä»¥ç´æ¥ç¨ç¬¬äºæ¬¡ dfs ç dfs åºã
```cpp
int bl[100002], bls = 0; //å±äºçåï¼åçæ°é
@@ -657,140 +661,142 @@ if (!sta.empty()) {
ç±äºå¤äºæ¶é´ç»´ï¼åç大å°åå° 0.6 çæ ·å就差ä¸å¤äº
-```cpp
-#include
-//#pragma GCC optimize(2)
-using namespace std;
-inline int gi() {
- register int x, c, op = 1;
- while (c = getchar(), c < '0' || c > '9')
- if (c == '-') op = -op;
- x = c ^ 48;
- while (c = getchar(), c >= '0' && c <= '9')
- x = (x << 3) + (x << 1) + (c ^ 48);
- return x * op;
-}
-int head[100002], nxt[200004], ver[200004], tot = 0;
-void add(int x, int y) {
- ver[++tot] = y, nxt[tot] = head[x], head[x] = tot;
- ver[++tot] = x, nxt[tot] = head[y], head[y] = tot;
-}
-int bl[100002], bls = 0;
-unsigned step;
-int fa[100002], dp[100002], hs[100002] = {0}, sz[100002] = {0}, top[100002],
- id[100002];
-stack sta;
-void dfs1(int x) {
- sz[x] = 1;
- unsigned ss = sta.size();
- for (int i = head[x]; i; i = nxt[i])
- if (ver[i] != fa[x]) {
- fa[ver[i]] = x, dp[ver[i]] = dp[x] + 1;
- dfs1(ver[i]);
- sz[x] += sz[ver[i]];
- if (sz[ver[i]] > sz[hs[x]]) hs[x] = ver[i];
- if (sta.size() - ss >= step) {
+??? åè代ç
+
+ ```cpp
+ #include
+ //#pragma GCC optimize(2)
+ using namespace std;
+ inline int gi() {
+ register int x, c, op = 1;
+ while (c = getchar(), c < '0' || c > '9')
+ if (c == '-') op = -op;
+ x = c ^ 48;
+ while (c = getchar(), c >= '0' && c <= '9')
+ x = (x << 3) + (x << 1) + (c ^ 48);
+ return x * op;
+ }
+ int head[100002], nxt[200004], ver[200004], tot = 0;
+ void add(int x, int y) {
+ ver[++tot] = y, nxt[tot] = head[x], head[x] = tot;
+ ver[++tot] = x, nxt[tot] = head[y], head[y] = tot;
+ }
+ int bl[100002], bls = 0;
+ unsigned step;
+ int fa[100002], dp[100002], hs[100002] = {0}, sz[100002] = {0}, top[100002],
+ id[100002];
+ stack sta;
+ void dfs1(int x) {
+ sz[x] = 1;
+ unsigned ss = sta.size();
+ for (int i = head[x]; i; i = nxt[i])
+ if (ver[i] != fa[x]) {
+ fa[ver[i]] = x, dp[ver[i]] = dp[x] + 1;
+ dfs1(ver[i]);
+ sz[x] += sz[ver[i]];
+ if (sz[ver[i]] > sz[hs[x]]) hs[x] = ver[i];
+ if (sta.size() - ss >= step) {
+ bls++;
+ while (sta.size() != ss) bl[sta.top()] = bls, sta.pop();
+ }
+ }
+ sta.push(x);
+ }
+ int cnt = 0;
+ void dfs2(int x, int hf) {
+ top[x] = hf, id[x] = ++cnt;
+ if (!hs[x]) return;
+ dfs2(hs[x], hf);
+ for (int i = head[x]; i; i = nxt[i])
+ if (ver[i] != fa[x] && ver[i] != hs[x]) dfs2(ver[i], ver[i]);
+ }
+ int lca(int x, int y) {
+ while (top[x] != top[y]) {
+ if (dp[top[x]] < dp[top[y]]) swap(x, y);
+ x = fa[top[x]];
+ }
+ return dp[x] < dp[y] ? x : y;
+ }
+ struct qu {
+ int x, y, t, id;
+ bool operator<(const qu a) const {
+ return bl[x] == bl[a.x] ? (bl[y] == bl[a.y] ? t < a.t : bl[y] < bl[a.y])
+ : bl[x] < bl[a.x];
+ }
+ } q[100001];
+ int qs = 0;
+ struct ch {
+ int x, y, b;
+ } upd[100001];
+ int ups = 0;
+ long long ans[100001];
+ int b[100001] = {0};
+ int a[100001];
+ long long w[100001];
+ long long v[100001];
+ long long now = 0;
+ bool vis[100001] = {0};
+ void back(int t) {
+ if (vis[upd[t].x]) {
+ now -= w[b[upd[t].y]--] * v[upd[t].y];
+ now += w[++b[upd[t].b]] * v[upd[t].b];
+ }
+ a[upd[t].x] = upd[t].b;
+ }
+ void change(int t) {
+ if (vis[upd[t].x]) {
+ now -= w[b[upd[t].b]--] * v[upd[t].b];
+ now += w[++b[upd[t].y]] * v[upd[t].y];
+ }
+ a[upd[t].x] = upd[t].y;
+ }
+ void update(int x) {
+ if (vis[x])
+ now -= w[b[a[x]]--] * v[a[x]];
+ else
+ now += w[++b[a[x]]] * v[a[x]];
+ vis[x] ^= 1;
+ }
+ void move(int x, int y) {
+ if (dp[x] < dp[y]) swap(x, y);
+ while (dp[x] > dp[y]) update(x), x = fa[x];
+ while (x != y) update(x), update(y), x = fa[x], y = fa[y];
+ }
+ int main() {
+ int n = gi(), m = gi(), k = gi();
+ step = (int)pow(n, 0.6);
+ for (int i = 1; i <= m; i++) v[i] = gi();
+ for (int i = 1; i <= n; i++) w[i] = gi();
+ for (int i = 1; i < n; i++) add(gi(), gi());
+ for (int i = 1; i <= n; i++) a[i] = gi();
+ for (int i = 1; i <= k; i++)
+ if (gi())
+ q[++qs].x = gi(), q[qs].y = gi(), q[qs].t = ups, q[qs].id = qs;
+ else
+ upd[++ups].x = gi(), upd[ups].y = gi();
+ for (int i = 1; i <= ups; i++) upd[i].b = a[upd[i].x], a[upd[i].x] = upd[i].y;
+ for (int i = ups; i; i--) back(i);
+ fa[1] = 1;
+ dfs1(1), dfs2(1, 1);
+ if (!sta.empty()) {
bls++;
- while (sta.size() != ss) bl[sta.top()] = bls, sta.pop();
+ while (!sta.empty()) bl[sta.top()] = bls, sta.pop();
+ }
+ for (int i = 1; i <= n; i++)
+ if (id[q[i].x] > id[q[i].y]) swap(q[i].x, q[i].y);
+ sort(q + 1, q + qs + 1);
+ int x = 1, y = 1, t = 0;
+ for (int i = 1; i <= qs; i++) {
+ if (x != q[i].x) move(x, q[i].x), x = q[i].x;
+ if (y != q[i].y) move(y, q[i].y), y = q[i].y;
+ int f = lca(x, y);
+ update(f);
+ while (t < q[i].t) change(++t);
+ while (t > q[i].t) back(t--);
+ ans[q[i].id] = now;
+ update(f);
}
+ for (int i = 1; i <= qs; i++) printf("%lld\n", ans[i]);
+ return 0;
}
- sta.push(x);
-}
-int cnt = 0;
-void dfs2(int x, int hf) {
- top[x] = hf, id[x] = ++cnt;
- if (!hs[x]) return;
- dfs2(hs[x], hf);
- for (int i = head[x]; i; i = nxt[i])
- if (ver[i] != fa[x] && ver[i] != hs[x]) dfs2(ver[i], ver[i]);
-}
-int lca(int x, int y) {
- while (top[x] != top[y]) {
- if (dp[top[x]] < dp[top[y]]) swap(x, y);
- x = fa[top[x]];
- }
- return dp[x] < dp[y] ? x : y;
-}
-struct qu {
- int x, y, t, id;
- bool operator<(const qu a) const {
- return bl[x] == bl[a.x] ? (bl[y] == bl[a.y] ? t < a.t : bl[y] < bl[a.y])
- : bl[x] < bl[a.x];
- }
-} q[100001];
-int qs = 0;
-struct ch {
- int x, y, b;
-} upd[100001];
-int ups = 0;
-long long ans[100001];
-int b[100001] = {0};
-int a[100001];
-long long w[100001];
-long long v[100001];
-long long now = 0;
-bool vis[100001] = {0};
-void back(int t) {
- if (vis[upd[t].x]) {
- now -= w[b[upd[t].y]--] * v[upd[t].y];
- now += w[++b[upd[t].b]] * v[upd[t].b];
- }
- a[upd[t].x] = upd[t].b;
-}
-void change(int t) {
- if (vis[upd[t].x]) {
- now -= w[b[upd[t].b]--] * v[upd[t].b];
- now += w[++b[upd[t].y]] * v[upd[t].y];
- }
- a[upd[t].x] = upd[t].y;
-}
-void update(int x) {
- if (vis[x])
- now -= w[b[a[x]]--] * v[a[x]];
- else
- now += w[++b[a[x]]] * v[a[x]];
- vis[x] ^= 1;
-}
-void move(int x, int y) {
- if (dp[x] < dp[y]) swap(x, y);
- while (dp[x] > dp[y]) update(x), x = fa[x];
- while (x != y) update(x), update(y), x = fa[x], y = fa[y];
-}
-int main() {
- int n = gi(), m = gi(), k = gi();
- step = (int)pow(n, 0.6);
- for (int i = 1; i <= m; i++) v[i] = gi();
- for (int i = 1; i <= n; i++) w[i] = gi();
- for (int i = 1; i < n; i++) add(gi(), gi());
- for (int i = 1; i <= n; i++) a[i] = gi();
- for (int i = 1; i <= k; i++)
- if (gi())
- q[++qs].x = gi(), q[qs].y = gi(), q[qs].t = ups, q[qs].id = qs;
- else
- upd[++ups].x = gi(), upd[ups].y = gi();
- for (int i = 1; i <= ups; i++) upd[i].b = a[upd[i].x], a[upd[i].x] = upd[i].y;
- for (int i = ups; i; i--) back(i);
- fa[1] = 1;
- dfs1(1), dfs2(1, 1);
- if (!sta.empty()) {
- bls++;
- while (!sta.empty()) bl[sta.top()] = bls, sta.pop();
- }
- for (int i = 1; i <= n; i++)
- if (id[q[i].x] > id[q[i].y]) swap(q[i].x, q[i].y);
- sort(q + 1, q + qs + 1);
- int x = 1, y = 1, t = 0;
- for (int i = 1; i <= qs; i++) {
- if (x != q[i].x) move(x, q[i].x), x = q[i].x;
- if (y != q[i].y) move(y, q[i].y), y = q[i].y;
- int f = lca(x, y);
- update(f);
- while (t < q[i].t) change(++t);
- while (t > q[i].t) back(t--);
- ans[q[i].id] = now;
- update(f);
- }
- for (int i = 1; i <= qs; i++) printf("%lld\n", ans[i]);
- return 0;
-}
-```
+ ```
--
2.11.0