不是萌新, 我的程序做错了什么QAQ

SP10628 COT - Count on a tree

``` #include <iostream> #include <cstring> #include <cmath> #include <cstdio> #include <algorithm> #include <ctime> #define maxn 100010 #define maxs 330 #define re register #define FOR(i, l, r) for(re int i = l; i <= r; ++i) using namespace std; int n, m, c, r, t, x, y, k; int sq1, sq2, num, cnt, col, theone, fh, lastans; int a[maxn], b[maxn], depth[maxn], cnt1[maxs*2][maxs], cnt2[maxs*2][maxn]; int qwq[maxn], san1[maxn], san2[maxn], dis[maxn], head[maxn], numb[maxn]; int fa[maxn], siz[maxn], son[maxn], near[maxn], top[maxn], z[maxn], z1[maxn]; struct hz { int next; int to; }h[maxn*2]; inline int read(){ int x=0;int f=1;char c=getchar(); while(c<'0'||c>'9'){ if(c==-1) return 0; if(c=='-')f=-1; c=getchar(); } while(c<='9'&&c>='0'){ x=(x<<1)+(x<<3)+(c^'0'); c=getchar(); } return x*f; } inline void add(int from, int to) { h[++num].next = head[from]; h[num].to = to; head[from] = num; } void dfs1(int x, int f) { fa[x] = f; siz[x] = 1; depth[x] = depth[f]+1; for(re int i = head[x]; i != 0; i = h[i].next) { if(h[i].to == f) continue; dfs1(h[i].to, x); siz[x] += siz[h[i].to]; if(siz[h[i].to] > siz[son[x]]) son[x] = h[i].to; } } void dfs2(int x, int topf) { top[x] = topf; if(!son[x]) return; dfs2(son[x], topf); for(re int i = head[x]; i != 0; i = h[i].next) { if(h[i].to == fa[x] || h[i].to == son[x]) continue; dfs2(h[i].to, h[i].to); } } inline int lca(int x, int y) { while(top[x] != top[y]) { if(depth[top[x]] < depth[top[y]]) swap(x, y); x = fa[top[x]]; } if(depth[x] > depth[y]) swap(x, y); return x; } void dfs3(int x, int color) { if(numb[x] != 0) color = numb[x]; near[x] = color; for(re int i = head[x]; i != 0; i = h[i].next) { if(h[i].to == fa[x]) continue; dfs3(h[i].to, color); } } inline void deal(int x, int times) { while(x != 0) { ++cnt1[times][b[a[x]]]; ++cnt2[times][a[x]]; x = fa[x]; } } int query(int x, int y, int k) { if(near[x] == near[y]) { int lc = lca(x, y), xx = x, yy = y, anss = 0; while(x != lc) ++san1[b[a[x]]], ++san2[a[x]], x = fa[x]; while(y != fa[lc]) ++san1[b[a[y]]], ++san2[a[y]], y = fa[y]; int tot = 0, now = 1; while(tot+san1[now] < k) tot += san1[now], ++now; FOR(j, (now-1)*sq1+1, now*sq1) if((tot += san2[j]) >= k) { anss = z[j]; break; } while(xx != lc) --san1[b[a[xx]]], --san2[a[xx]], xx = fa[xx]; while(yy != fa[lc]) --san1[b[a[yy]]], --san2[a[yy]], yy = fa[yy]; return anss; } int lc = lca(x, y), LC = lca(z1[near[x]], z1[near[y]]), xx = x, yy = y; theone = -1, fh = 1; if(lca(z1[near[x]], z1[near[y]]) == LC && (lca(lc, z1[near[x]]) == lc || lca(lc, z1[near[y]])) && lc != LC) { //需要转化加减答案 theone = lc; san1[b[a[LC]]]--, san2[a[LC]]--; } while(near[fa[xx]] == near[x]) { if(xx == theone) { fh *= -1; } else { san1[b[a[xx]]] += fh, san2[a[xx]] += fh; } if(xx == 0) exit(0); xx = fa[xx]; } fh = 1; while(near[fa[yy]] == near[y]) { if(yy == theone) { fh *= -1; yy = fa[yy]; continue; } san1[b[a[yy]]] += fh, san2[a[yy]] += fh, yy = fa[yy]; } ++san1[b[a[LC]]]; ++san2[a[LC]]; int tot = 0, now = 1, anss = 0; while(tot+san1[now]+cnt1[near[x]][now]+cnt1[near[y]][now]-2*cnt1[numb[LC]][now] < k) tot += san1[now]+cnt1[near[x]][now]+cnt1[near[y]][now]-2*cnt1[numb[LC]][now], ++now; FOR(j, (now-1)*sq1+1, now*sq1) if((tot += san2[j]+cnt2[near[x]][j]+cnt2[near[y]][j]-2*cnt2[numb[LC]][j]) >= k) { anss = z[j]; break; } fh = -1, xx = x, yy = y; while(near[fa[xx]] == near[x]) { if(xx == theone) { fh *= -1; xx = fa[xx]; continue; } san1[b[a[xx]]] += fh, san2[a[xx]] += fh, xx = fa[xx]; } fh = -1; while(near[fa[yy]] == near[y]) { if(yy == theone) { fh *= -1; yy = fa[yy]; continue; } san1[b[a[yy]]] += fh, san2[a[yy]] += fh, yy = fa[yy]; } --san1[b[a[LC]]]; --san2[a[LC]]; if(lca(z1[near[x]], z1[near[y]]) == LC && (lca(lc, z1[near[x]]) == lc || lca(lc, z1[near[y]])) && lc != LC) { //需要转化加减答案 san1[b[a[LC]]]++, san2[a[LC]]++; } return anss; } signed main() { srand(19260817); srand(rand()); srand(rand()); n = read(), m = read(); FOR(i, 1, n) { a[i] = read(), z[++z[0]] = a[i]; qwq[i] = i; } FOR(i, 1, n-1) { x = read(), y = read(); add(x, y); add(y, x); } sort(z+1, z+z[0]+1); z[0] = unique(z+1, z+z[0]+1)-z-1; FOR(i, 1, n) a[i] = lower_bound(z+1, z+z[0]+1, a[i])-z; sq1 = sqrt(z[0]); FOR(i, 1, z[0]) b[i] = (i-1)/sq1+1; random_shuffle(qwq+1, qwq+n+1); sq2 = sqrt(n); FOR(i, 1, sq2) z1[++z1[0]] = qwq[i]; dfs1(1, 0); dfs2(1, 1); FOR(i, 1, sq2) FOR(j, i+1, sq2) z1[++z1[0]] = lca(qwq[i], qwq[j]); sort(z1+1, z1+z1[0]+1); z1[0] = unique(z1+1, z1+z1[0]+1)-z1-1; FOR(i, 1, z1[0]) numb[z1[i]] = i; dfs3(1, -2); FOR(i, 1, z1[0]) deal(z1[i], i); FOR(i, 1, m) { x = read(), y = read(), k = read(); printf("%d\n", query(x, y, k)); } } ```
by Juan_feng @ 2019-08-18 14:50:00


小学生发来惊讶的Orz 您竟然会我们不可望也不可及的算法
by yinxiaodi2006 @ 2019-08-18 14:51:45


算法正确性没有问题qwq 已经通过类似的题目了。 做法是往树里面撒关键点然后值域分块处理前缀信息, 查询的时候讨论一下就行了...
by Juan_feng @ 2019-08-18 14:53:04


@[Juan_feng](/space/show?uid=66965) ~~没事,我的主席树也UKE了~~
by Smile_Cindy @ 2019-08-18 14:53:38


SPOJ的问题,我在vjudge上也交不上去
by Smile_Cindy @ 2019-08-18 14:54:42


@[Alpha](/space/show?uid=87058) 我刚刚又交了一遍主席树过了... 交的树上莫队也不会UKE。。。 就针对我分块QAQ
by Juan_feng @ 2019-08-18 14:54:55


qwq
by chenxia25 @ 2019-08-18 14:54:56


原来用主席树A过一遍的
by Smile_Cindy @ 2019-08-18 14:55:16


注意: 我在短时间之内提交了多种代码。 其中只有我的分块uke了......
by Juan_feng @ 2019-08-18 14:55:32


@[Juan_feng](/space/show?uid=66965) 提交记录发一下
by Smile_Cindy @ 2019-08-18 14:56:14


| 下一页