// Code By CloudySky #include<iostream> #include<cstdio> #include<algorithm> #include<set> #define int long long namespace IO { inlineintread(){ int x = 0, f = 1; char c = getchar(); while (c < '0' || c > '9') { if (c == '-') f = -1; c = getchar(); } while (c >= '0' && c <= '9') { x = x * 10 + (c ^ 48); c = getchar(); } return x * f; } voidprint_n(int x){ if (x > 9) print_n(x / 10); putchar(x % 10 + '0'); } inlinevoidprint(int x, char s = '\n'){ if (x < 0) putchar('-'), x = -x; print_n(x), putchar(s); } } // namespace IO usingnamespace IO; constint Maxn = 5e5 + 10; usingnamespace std;
int a[Maxn]; set <int> s;
inlineintsolve(constint L, constint R, constint p){ int ans = 1e18; if (R - L >= p) return0; for (int i = L; i <= R; ++i) { int cur = ((a[i] - a[L - 1]) % p); auto t = s.upper_bound (cur); ans = min (ans, cur - *(--t)); s.insert (cur); } return ans; }
signedmain(){ #ifndef ONLINE_JUDGE freopen("in.in", "r", stdin); freopen("out.out", "w", stdout); #endif int n = read (), m = read (); for (int i = 1; i <= n; ++i) a[i] = a[i - 1] + read (); for (int i = 1; i <= m; ++i) { int L = read (), R = read (), p = read (); s.clear (); s.insert (0); print (solve (L, R, p)); } return0; }
voidbuild(int p, int l, int r){ if (l == r) returninit(p, l); int mid = (l + r) >> 1; build(ls, l, mid), build(rs, mid + 1, r); St[p] = merge(St[ls], St[rs]); }
voidask(int p, int l, int r, int ql, int qr){ if (l > qr || r < ql) return; if (l >= ql && r <= qr) { if (!flag) T = St[p], flag = 1; else T = merge(T, St[p]); return; } int mid = (l + r) >> 1; ask(ls, l, mid, ql, qr), ask(rs, mid + 1, r, ql, qr); }
signedmain(){ openfile(); int n = read(), m = read(); for (int i = 1, u, v; i < n; ++i) u = read(), v = read(), add(u, v), add(v, u); dfs(1, 0), build(1, 1, tot); for (int i = 1; i <= m; ++i) { int u = read(), v = read(); if (in[u] > in[v]) swap(u, v); print(Ask(u, v)); } return0; }
// Code By CloudySky #include<bits/stdc++.h> #define int long long namespace IO { inlineintread(){ int x = 0, f = 1; char c = getchar(); while (c < '0' || c > '9') { if (c == '-') f = -1; c = getchar(); } while (c >= '0' && c <= '9') { x = x * 10 + (c ^ 48); c = getchar(); } return x * f; } inlineintread_c(){ char c = getchar(); while (c<'A'||c>'B')c=getchar(); if (c>='A'&&c<='B')return c; } voidprint_n(int x){ if (x > 9) print_n(x / 10); putchar(x % 10 + '0'); } inlinevoidprint(int x, char s = '\n'){ if (x < 0) putchar('-'), x = -x; print_n(x), putchar(s); } } // namespace IO usingnamespace IO; constint Maxn = 1e5 + 10; usingnamespace std;
structnode { int l, r; booloperator < (const node y) const { return l + r < y.l + y.r; } } a[Maxn]; int tot, suml, sumr, ansl[Maxn], ansr[Maxn];
// Code By CloudySky #include<bits/stdc++.h> // #define int long long namespace IO { inlineintread(){ int x = 0, f = 1; char c = getchar(); while (c < '0' || c > '9') { if (c == '-') f = -1; c = getchar(); } while (c >= '0' && c <= '9') { x = x * 10 + (c ^ 48); c = getchar(); } return x * f; } voidprint_n(int x){ if (x > 9) print_n(x / 10); putchar(x % 10 + '0'); } inlinevoidprint(int x, char s = '\n'){ if (x < 0) putchar('-'), x = -x; print_n(x), putchar(s); } } // namespace IO usingnamespace IO; constint Maxn = 1e5 + 10; usingnamespace std;
int ac[Maxn][26], tot, fail[Maxn], fa[Maxn], id[Maxn], cnt; vector <int> val[Maxn];
voidinsert(char* s){ int n = strlen (s), p = 0; while (s[n - 1] != 'P') n--; for (int i = 0; i < n; ++i) { if (s[i] == 'B') p = fa[p]; elseif (s[i] == 'P') val[p].push_back (++cnt), id[cnt] = p; else { if (!ac[p][s[i] - 'a']) ac[p][s[i] - 'a'] = ++tot, fa[tot] = p; p = ac[p][s[i] - 'a']; } } }
queue <int> q; vector <int> g[Maxn];
voidbuild(){ for (int i = 0; i < 26; ++i) if (ac[0][i]) q.push (ac[0][i]); while (!q.empty ()) { int p = q.front (); q.pop (); g[fail[p]].push_back (p); for (int i = 0; i < 26; ++i) { int np = ac[fail[p]][i]; if (ac[p][i]) fail[ac[p][i]] = np, q.push (ac[p][i]); else ac[p][i] = np; } } }
int v[Maxn]; voidadd(int x, int k){ for (; x <= tot; x += (x & -x)) v[x] += k; }
intask(int x, int ans = 0){ for (; x; x -= (x & -x)) ans += v[x]; return ans; }
int dfn[Maxn], siz[Maxn], tim;
voiddfs(int x){ dfn[x] = ++tim, siz[x] = 1; for (int y : g[x]) dfs(y), siz[x] += siz[y]; }
int trie[Maxn][26], ans[Maxn]; structnode { int x, id; }; vector <node> query[Maxn];
voidsolve(int x){ add (dfn[x], 1); for (int i : val[x]) for (node k : query[i]) { int y = id[k.x]; ans[k.id] = ask (dfn[y] + siz[y] - 1) - ask (dfn[y] - 1); } for (int i = 0; i < 26; ++i) if (trie[x][i]) solve (trie[x][i]); add (dfn[x], -1); }
char s[Maxn];
signedmain(){ // #ifndef ONLINE_JUDGE // freopen("in.in", "r", stdin); // freopen("out.out", "w", stdout); // #endif scanf ("%s", s); insert (s); memcpy (trie, ac, sizeof (ac)); build (); int m = read (); for (int i = 1; i <= m; ++i) { int x = read (), y = read (); query[y].push_back ((node) {x, i}); } ++tot; dfs (0), solve (0); for (int i = 1; i <= m; ++i) print (ans[i]); return0; }
// Code By CloudySky #include<bits/stdc++.h> // #define int long long namespace IO { inlineintread(){ int x = 0, f = 1; char c = getchar(); while (c < '0' || c > '9') {if (c == '-') f = -1; c = getchar();} while (c >= '0' && c <= '9') x = x * 10 + (c ^ 48), c = getchar(); return x * f; } voidprint_n(int x){ if (x > 9) print_n(x / 10); putchar(x % 10 + '0'); } inlinevoidprint(int x, char s = '\n'){ if (x < 0) putchar('-'), x = -x; print_n(x), putchar(s); } } // namespace IO usingnamespace IO; voidopenfile(); constint Maxn = 1e6 + 10; usingnamespace std;
structnode { int x, y, id; booloperator < (const node b) const {return y > b.y;} } p[Maxn];
structedge {int v, nxt;} e[Maxn << 1]; int hd[Maxn], cnt; voidadd(int u, int v){e[++cnt] = {v, hd[u]}, hd[u] = cnt;} vector <int> g[Maxn];
int dfn[Maxn], low[Maxn], tim, col[Maxn], vis[Maxn]; int stc[Maxn], top;
int A, B; vector <node> a, b;
voiddfs(int x){ dfn[x] = low[x] = ++tim; stc[++top] = x, vis[x] = 1; if (p[x].x == A) b.push_back(p[x]); for (int y : g[x]) { if (!dfn[y]) dfs(y), low[x] = min(low[x], low[y]); elseif (vis[y]) low[x] = min(low[x], dfn[y]); } if (dfn[x] == low[x]) { int y; while ((y = stc[top--]) != 0) { vis[y] = 0, col[y] = x; if (y == x) break; } } }
int mx[Maxn], mn[Maxn];
voiddfs2(int x){ if (vis[x]) return; vis[x] = 1; for (int i = hd[x]; i; i = e[i].nxt) { int y = e[i].v; dfs2(y); mx[x] = max(mx[x], mx[y]), mn[x] = min(mn[x], mn[y]); } }
signedmain(){ openfile(); int n = read(), m = read(); A = read(), B = read(); for (int i = 1; i <= n; ++i) p[i] = {read(), read(), i}; for (int i = 1; i <= n; ++i) if (p[i].x == 0) a.push_back(p[i]); for (int i = 1, u, v, t; i <= m; ++i) { u = read(), v = read(), t = read(); g[u].push_back(v); if (t == 2) g[v].push_back(u); } for (int i = 1; i <= n; ++i) if (!p[i].x) if (!dfn[i]) dfs(i); for (int u = 1; u <= n; ++u) for (int v : g[u]) if (col[u] != col[v]) add(col[u], col[v]); sort(a.begin(), a.end()), sort(b.begin(), b.end()); memset(mn, 0x3f, sizeof(mn)); for (auto x : b) { int _col = col[x.id], pos = lower_bound(b.begin(), b.end(), x) - b.begin() + 1; mx[_col] = max(mx[_col], pos), mn[_col] = min(mn[_col], pos); } memset(vis, 0, sizeof(vis)); for (auto u : a) dfs2(col[u.id]), print(max(0, mx[col[u.id]] - mn[col[u.id]] + 1)); return0; }
// Code By CloudySky #include<bits/stdc++.h> #define int long long namespace IO { inlineintread(){ int x = 0, f = 1; char c = getchar(); while (c < '0' || c > '9') { if (c == '-') f = -1; c = getchar(); } while (c >= '0' && c <= '9') { x = x * 10 + (c ^ 48); c = getchar(); } return x * f; } voidprint_n(int x){ if (x > 9) print_n(x / 10); putchar(x % 10 + '0'); } inlinevoidprint(int x, char s = '\n'){ if (x < 0) putchar('-'), x = -x; print_n(x), putchar(s); } } // namespace IO usingnamespace IO; constint Maxn = 1e5 + 10; usingnamespace std;
intgcd(int a, int b){ return !b ? a : gcd (b, a % b); } vector <int> g;
voidcalc(int x){ g.clear (); for (int i = 2; i * i <= x; ++i) { if (x % i ==0) { g.push_back (i); while (x % i == 0) x /= i; } } if (x > 1) g.push_back (x); }
voidwork(){ int a = read (), b = read (), c = read (); if (!a) { printf ("YES\n"); return; } int d = gcd (a, b); a /= d, b /= d; while (b != 1) { int d = gcd (b, c); if (d == 1) { printf ("NO\n"); return;} b /= d, c = d; } printf ("YES\n"); return; }
signedmain(){ #ifndef ONLINE_JUDGE freopen("in.in", "r", stdin); freopen("out.out", "w", stdout); #endif signed t = read (); while (t--) work (); return0; }
T2 [常中20181205 T3]-Travel
题目描述
给定一个长度为 n 的序列 xi 保证 ∀i<j,xi<xj ,起始位置 s,和需要向左跳的次数 L。你需要正好跳 n−1 次,不重不漏地经过序列上的每个点。从 i 到 j 的贡献为 ∣xi−xj∣ 。
// Code By CloudySky #include<bits/stdc++.h> // #define int long long namespace IO { inlineintread(){ int x = 0, f = 1; char c = getchar(); while (c < '0' || c > '9') { if (c == '-') f = -1; c = getchar(); } while (c >= '0' && c <= '9') { x = x * 10 + (c ^ 48); c = getchar(); } return x * f; } voidprint_n(int x){ if (x > 9) print_n(x / 10); putchar(x % 10 + '0'); } inlinevoidprint(int x, char s = '\n'){ if (x < 0) putchar('-'), x = -x; print_n(x), putchar(s); } } // namespace IO usingnamespace IO; constint Maxn = 1e6 + 10; usingnamespace std;
int a[Maxn], n;
intsolve(int s, int l, vector <int>& Ans){ staticint rk[Maxn], tag[Maxn]; // 特判 2,L < s 直接贪心即可 if (l < s) { for (int i = s - 1; i > s - l; --i) Ans.push_back (i); for (int i = 1; i <= s - l; ++i) Ans.push_back (i); for (int i = s + 1; i <= n; ++i) Ans.push_back (i); return a[s] - a[1] + a[n] - a[1]; } // 特判 3,L == n - 2 解法唯一,直接反回 if (l == n - 2) { for (int i = s - 1; i >= 1; --i) Ans.push_back (i); for (int i = n; i > s; --i) Ans.push_back (i); return2 * (a[n] - a[1]) - (a[s + 1] - a[s]); } // 开始主要部分 l -= s - 1; // s 左边全向左走,剩下的 l 在 s 右边完成 static vector <pair <int,int > > pos; // 用来记录备选需要重复走的线段 pos.clear (), pos.push_back ({0, 0}); for (int i = s + 2; i < n; ++i) pos.push_back ({a[i] - a[i - 1], i}); sort (pos.begin () + 1, pos.end ()); for (unsigned i = 1; i < pos.size (); ++i) rk[pos[i].second] = i; int mn = 0, sum = 0; // mn 记录最小的总额外长度,sum 记录绕圈总长度 for (int i = 1; i <= l; ++i) sum += pos[i].first; mn = 2 * sum; int t = n, j = l; // t 为最终的结束位置,j 为最后一个令答案改变的线段排名 for (int i = n - 1, p = l; i >= n - l; --i) { if (rk[i] <= p) sum -= pos[rk[i]].first; else sum -= pos[p--].first; while (p && pos[p].second >= i) p--; if (sum * 2 + a[n] - a[i] < mn) mn = sum * 2 + a[n] - a[i], t = i, j = p; } // 开始构造方案 memset (tag, 0, sizeof (tag)); for (int i = s - 1; i >= 1; --i) Ans.push_back (i); for (int i = s + 2; i < t; ++i) if (rk[i] <= j) tag[i] = 1; for (int i = s + 1; i < t; ++i) { if (!tag[i + 1]) Ans.push_back (i); else { int k = i + 1; while (tag[k]) ++k; for (int j = k - 1; j >= i; --j) Ans.push_back (j); i = k - 1; } } for (int i = n; i >= t; --i) Ans.push_back (i); return a[s] - a[1] + a[n] - a[1] + mn; }
signedmain(){ #ifndef ONLINE_JUDGE freopen("in.in", "r", stdin); freopen("out.out", "w", stdout); #endif staticint t[Maxn]; static vector <int> Ans1, Ans2; n = read (); int l = read (), s = read (); for (int i = 1; i <= n; ++i) a[i] = read (), t[i] = a[i]; // 特判 1,L 范围不合法,无解 if (l == 0 && s != 1) { print (-1); return0;} if (l == n - 1 && s != n) {print (-1); return0;} // 进行对称处理 int ans1 = solve (s, l, Ans1); for (int i = 1; i <= n; ++i) a[i] = -t[n - i + 1]; int ans2 = solve (n - s + 1, n - l - 1, Ans2); // 比较两次答案并输出结果 if (ans1 < ans2) { print (ans1); for (int i : Ans1) print (i, ' '); } else { print (ans2); for (int i : Ans2) print (n - i + 1, ' '); } return0; }
2.10 / 模拟赛 6
T1 常中20181205T1-Simple
题目描述
对于给定正整数 n,m,我们称正整数 c 为好的,当且仅当存在非负整数 x,y,使得 nx+my=c。 现在给出多组数据,对于每组数据,给定 n,m,q,求 [1,q] 内有多少个正整数不是好的。
思路
考场上打了个巨大的表,横轴代表 x 选择个数(n),纵轴代表 y 选择个数(m)。然后发现只有前 gcd(x,y) 行是有用的。就直接开冲了。
// Code By CloudySky #include<bits/stdc++.h> #define int long long namespace IO { inlineintread(){ int x = 0, f = 1; char c = getchar(); while (c < '0' || c > '9') { if (c == '-') f = -1; c = getchar(); } while (c >= '0' && c <= '9') { x = x * 10 + (c ^ 48); c = getchar(); } return x * f; } voidprint_n(int x){ if (x > 9) print_n(x / 10); putchar(x % 10 + '0'); } inlinevoidprint(int x, char s = '\n'){ if (x < 0) putchar('-'), x = -x; print_n(x), putchar(s); } } // namespace IO usingnamespace IO; usingnamespace std;
intgcd(int a, int b){ return !b ? a : gcd (b, a % b); } intlcm(int a, int b){ return a * b / gcd (a, b); }
inlineintask(int a, int b, int q){ if (a < b) swap (a, b); bool ck1 = !a || a > q, ck2 = !b || b > q; if (ck1 && ck2) return q; if (ck1) return q - q / b; if (ck2) return q - q / a; int ans = 0, up = b / gcd (a, b); for (int i = 0; i < up; ++i) { if (i * a > q) break; ans += (q - i * a) / b + 1; } return q - ans + 1; }
signedmain(){ #ifndef ONLINE_JUDGE freopen("in.in", "r", stdin); freopen("out.out", "w", stdout); #endif int t = read (); while (t --) { int a = read (), b = read (), q = read (); print (ask (a, b, q)); } return0; }
T2 常中20181205T2-Walk
题目描述
给定一个 n 个节点的树,求长度为 i 的路径中所有边权 gcd 最大是多少。
思路
最大公约数不好像边权和那样贪心选择。于是考虑枚举 d ,在边权为 d 的倍数的子图上跑直径。最后跑一个后缀 max。
// Code By CloudySky #include<bits/stdc++.h> // #define int long long namespace IO { inlineintread(){ int x = 0, f = 1; char c = getchar(); while (c < '0' || c > '9') { if (c == '-') f = -1; c = getchar(); } while (c >= '0' && c <= '9') { x = x * 10 + (c ^ 48); c = getchar(); } return x * f; } voidprint_n(int x){ if (x > 9) print_n(x / 10); putchar(x % 10 + '0'); } inlinevoidprint(int x, char s = '\n'){ if (x < 0) putchar('-'), x = -x; print_n(x), putchar(s); } } // namespace IO usingnamespace IO; constint Maxn = 4e5 + 10, Maxw = 1e6 + 10; usingnamespace std;
vector <pair<int, int> > E[Maxw]; int stc[Maxn << 1], ans[Maxn];
inlineintMax(int a, int b){ return a > b ? a : b;}
structedge { int v, nxt; } e[Maxn << 1]; int hd[Maxn], cnt; voidadd(int u, int v){ e[++cnt] = (edge) {v, hd[u]}; hd[u] = cnt, stc[cnt] = u; }
int d; bool vis[Maxn];
inlineintdfs(int x, int f){ vis[x] = 1; int mx = 0, sm = 0, len; for (int i = hd[x]; i; i = e[i].nxt) { int y = e[i].v; if (y == f || vis[y]) continue; len = dfs (y, x); if (len >= mx) sm = mx, mx = len; elseif (len > sm) sm = len; } d = Max (d, mx + sm); return mx + 1; }
signedmain(){ #ifndef ONLINE_JUDGE freopen("in.in", "r", stdin); freopen("out.out", "w", stdout); #endif int n = read (), mx = 0, u, v, w, siz; for (int i = 1; i < n; ++i) { u = read (), v = read (), w = read (); E[w].push_back ({u, v}), mx = Max (mx, w); } for (int w = 1; w <= mx; ++w) { for (int i = w; i <= mx; i += w) { siz = E[i].size (); for (int j = 0; j < siz; ++j) { u = E[i][j].first, v = E[i][j].second; add (u, v), add (v, u); } } for (int i = 1; i <= cnt; ++i) { int t = stc[i]; if (!vis[t]) dfs (t, 0); } ans[d] = w; for (int i = 1; i <= cnt; ++i) { int t = stc[i]; hd[t] = 0, vis[t] = 0; } d = cnt = 0; } for (int i = n; i; --i) ans[i] = Max (ans[i], ans[i + 1]); for (int i = 1; i <= n; ++i) print (ans[i]); return0; }
T3 树
题目描述
给定一棵 n 个结点的有根树 T,结点从 1 开始编号,根结点为 1 号结点,每个结点有一个正整数权值 vi。
设 x 号结点的子树内(包含 x 自身)的所有结点编号为 c1,c2,⋯,ck,定义 x 的价值为:
voidinsert(int& p, int val, int dep){ if (!p) p = ++tot; if (dep > 20) return vis[p] ^= 1, void(); insert(trie[p][val & 1], val >> 1, dep + 1); pushup(p); }
voidadd(int p){swap(ls(p), rs(p)); if (ls(p)) add(ls(p)); pushup(p);}
intmerge(int x, int y){ if (!x || !y) return x | y; val[x] ^= val[y], vis[x] ^= vis[y]; ls(x) = merge(ls(x), ls(y)); rs(x) = merge(rs(x), rs(y)); return x; }
voiddfs(int x){ for (int i = hd[x]; i; i = e[i].nxt) { int y = e[i].v; dfs(y); rt[x] = merge(rt[x], rt[y]); } add(rt[x]), insert(rt[x], a[x], 0); ans += 1ll * val[rt[x]]; }
signedmain(){ // openfile(); int n = read(); for (int i = 1; i <= n; ++i) a[i] = read(); for (int i = 2, f; i <= n; ++i) f = read(), add(f, i); dfs(1); print(ans); return0; }
// Code By CloudySky #include<bits/stdc++.h> // #define int long long namespace IO { inlineintread(){ int x = 0, f = 1; char c = getchar(); while (c < '0' || c > '9') {if (c == '-') f = -1; c = getchar();} while (c >= '0' && c <= '9') x = x * 10 + (c ^ 48), c = getchar(); return x * f; } voidprint_n(int x){ if (x > 9) print_n(x / 10); putchar(x % 10 + '0'); } inlinevoidprint(int x, char s = '\n'){ if (x < 0) putchar('-'), x = -x; print_n(x), putchar(s); } } // namespace IO usingnamespace IO; voidopenfile(); // const int Maxn = 1e5 + 10; usingnamespace std;
signedmain(){ openfile(); int n = read(), ans = 0; for (int i = 2; i <= n; i += 2) { for (int j = 1; (i + 1) * j <= n; ++j) if (j == (((i + 1) * j) ^ (i * j))) ++ans; } print(ans); return0; }
voidchange(int p, int v, int k){ if (l(p) == r(p)) {v(p) = k; return;} int mid = (l(p) + r(p)) >> 1; if (v <= mid) change(ls, v, k); elsechange(rs, v, k); v(p) = v(ls) + v(rs); }
intask(int p, int l, int r){ if (l(p) >= l && r(p) <= r) returnv(p); int mid = (l(p) + r(p)) >> 1, ans = 0; if (l <= mid) ans += ask(ls, l, r); if (r > mid) ans += ask(rs, l, r); return ans; }
structedge {int v, nxt;} e[Maxn << 1]; int hd[Maxn], cnt; voidadd(int u, int v){e[++cnt] = (edge) {v, hd[u]}; hd[u] = cnt;}
int dep[Maxn], siz[Maxn], fa[Maxn], son[Maxn]; voiddfs1(int x, int f){ dep[x] = dep[f] + 1, fa[x] = f, siz[x] = 1; for (int i = hd[x]; i; i = e[i].nxt) { int y = e[i].v; if (y == f) continue; dfs1(y, x), siz[x] += siz[y]; if (siz[y] > siz[son[x]]) son[x] = y; } }
int top[Maxn], dfn[Maxn], tim; voiddfs2(int x, int f){ top[x] = f, dfn[x] = ++tim, d[tim] = a[x]; if (son[x]) dfs2(son[x], f); for (int i = hd[x]; i; i = e[i].nxt) { int y = e[i].v; if (y != son[x] && y != fa[x]) dfs2(y, y); } }
intlca(int x, int y){ while (top[x] != top[y]) { if (dep[top[x]] < dep[top[y]]) swap(x, y); x = fa[top[x]]; } return dep[x] < dep[y] ? x : y; }
intqlink(int x, int y){ int ans = 0; while (top[x] != top[y]) { if (dep[top[x]] < dep[top[y]]) swap(x, y); ans += ask(1, dfn[top[x]], dfn[x]); x = fa[top[x]]; } if (dep[x] > dep[y]) swap(x, y); ans += ask(1, dfn[x], dfn[y]); return ans; }
intcheck(int x, int y){ int s = x; while(top[x] != top[y]) s = top[x], x = fa[top[x]]; if (fa[s] == y) return s; elsereturn son[y]; }
int root = 1, n, m; intqtree(int x){ if (x == root) returnask(1, 1, n); if (lca(x, root) != x) returnask(1, dfn[x], dfn[x] + siz[x] - 1); int kk = check(root, x); returnask(1, 1, n) - ask(1, dfn[kk], dfn[kk] + siz[kk] - 1); }
signedmain(){ n = read(), m = read(); for (int i = 1, u, v; i < n; ++i) u = read(), v = read(), add(u, v), add(v, u); for (int i = 1; i <= n; ++i) a[i] = read(); dfs1(1, 0), dfs2(1, 1), build(1, 1, n); for (int i = 1, op, x, v, y; i <= m; ++i) { op = read(), x = read(); if (op == 1) root = x; if (op == 2) v = read(), change(1, dfn[x], v); if (op == 3) print(qtree(x)); if (op == 4) y = read(), print(qlink(x, y)); } return0; }
T3 【20180819省队班】取数字
题目描述
给定 n 个整数 ai,你需要从中选取若干个数,使得它们的和是 m 的倍数。问有多少种方案。有多个询问,每次询问一个的 m 对应的答案。(m 远小于 n)