首页 > 代码库 > bzoj3159: 决战
bzoj3159: 决战
呀智障选手都快忘了代码怎么打了..
做这道题干啥咧..
GDOI2017D3T4.. dwjshift说很像这道题,然后就去做了..
然后就做了半个月??
简略解法
就是两棵LCT,一棵维护树的结构,一棵维护权值,两棵树在中序遍历上映射,所以维护一下根对根的映射即可
所以要怎么Access..
对于当前点$x$,在把它旋到当前splay的根的时候可以知道它在这棵splay上的排名
然后就去找对应的那棵权值splay的排名就知道映射的是哪个了啊..
然后.. 就没有然后了吧..
下面是代码呀..
#include <cstdio>#include <cstring>#include <cstdlib>#include <algorithm>#define LL long longusing namespace std;const LL Maxn = 50010;struct node { LL y, next;}a[Maxn*2]; LL first[Maxn], len;LL _max(LL x, LL y) { return x > y ? x : y; }LL _min(LL x, LL y) { return x < y ? x : y; }void ins(LL x, LL y) { len++; a[len].y = y; a[len].next = first[x]; first[x] = len;}LL n, m, r;LL p[Maxn];LL Maxx[Maxn], Minn[Maxn], sum[Maxn], val[Maxn];LL vfa[Maxn], fa[Maxn], sizef[Maxn], sizev[Maxn];LL cf[Maxn][2], cv[Maxn][2];LL revf[Maxn], revv[Maxn], la[Maxn];LL sta[Maxn], tp;char s[10];void dfs(LL x) { p[x] = x; sizef[x] = sizev[x] = 1; for(LL k = first[x]; k; k = a[k].next){ LL y = a[k].y; if(y == fa[x]) continue; fa[y] = x; vfa[y] = x; dfs(y); }}LL rt;/*f*/bool is_rootf(LL x) { return cf[fa[x]][0] != x && cf[fa[x]][1] != x; }void push_downf(LL x) { if(revf[x]){ swap(cf[x][0], cf[x][1]); revf[cf[x][0]] ^= 1; revf[cf[x][1]] ^= 1; revf[x] = 0; }}void prepf(LL x) { LL i; tp = 0; for(i = x; !is_rootf(i); i = fa[i]) sta[++tp] = i; sta[++tp] = i; for(i = tp; i >= 1; i--) push_downf(sta[i]);}void updatef(LL x) { sizef[x] = sizef[cf[x][0]]+sizef[cf[x][1]]+1; }void rotatef(LL x) { LL y = fa[x], z = fa[y], l, r; if(cf[y][0] == x) l = 0; else l = 1; r = l^1; if(!is_rootf(y)){ if(cf[z][0] == y) cf[z][0] = x; else cf[z][1] = x; } fa[x] = z; fa[y] = x; fa[cf[x][r]] = y; cf[y][l] = cf[x][r]; cf[x][r] = y; updatef(y);}void splayf(LL x) { rt = x; prepf(x); while(!is_rootf(x)){ LL y = fa[x], z = fa[y]; if(!is_rootf(y)){ if(is_rootf(z)) rt = z; if((cf[z][0] == y)^(cf[y][0] == x)) rotatef(x); else rotatef(y); } else rt = y; rotatef(x); } updatef(x);}/*v*/bool is_rootv(LL x) { return cv[vfa[x]][0] != x && cv[vfa[x]][1] != x; }void push_downv(LL x) { if(revv[x]){ swap(cv[x][0], cv[x][1]); revv[cv[x][0]] ^= 1; revv[cv[x][1]] ^= 1; revv[x] = 0; } if(la[x] > 0){ if(cv[x][0] > 0){ sum[cv[x][0]] += sizev[cv[x][0]]*la[x]; val[cv[x][0]] += la[x]; Maxx[cv[x][0]] += la[x]; Minn[cv[x][0]] += la[x]; la[cv[x][0]] += la[x]; } if(cv[x][1] > 0){ sum[cv[x][1]] += sizev[cv[x][1]]*la[x]; val[cv[x][1]] += la[x]; Maxx[cv[x][1]] += la[x]; Minn[cv[x][1]] += la[x]; la[cv[x][1]] += la[x]; } la[x] = 0; }}void prepv(LL x) { LL i; tp = 0; for(i = x; !is_rootv(i); i = vfa[i]) sta[++tp] = i; sta[++tp] = i; for(i = tp; i >= 1; i--) push_downv(sta[i]);}void updatev(LL x) { Maxx[x] = _max(Maxx[cv[x][0]], _max(Maxx[cv[x][1]], val[x])); Minn[x] = _min(Minn[cv[x][0]], _min(Minn[cv[x][1]], val[x])); sum[x] = sum[cv[x][0]]+sum[cv[x][1]]+val[x]; sizev[x] = sizev[cv[x][0]]+sizev[cv[x][1]]+1;}void rotatev(LL x) { LL y = vfa[x], z = vfa[y], l, r; if(cv[y][0] == x) l = 0; else l = 1; r = l^1; if(!is_rootv(y)){ if(cv[z][0] == y) cv[z][0] = x; else cv[z][1] = x; } vfa[x] = z; vfa[y] = x; vfa[cv[x][r]] = y; cv[y][l] = cv[x][r]; cv[x][r] = y; updatev(y);}void splayv(LL x) { prepv(x); while(!is_rootv(x)){ LL y = vfa[x], z = vfa[y]; if(!is_rootv(y)){ if((cv[z][0] == y)^(cv[y][0] == x)) rotatev(x); else rotatev(y); } rotatev(x); } updatev(x);}LL find_rank(LL x, LL p) { push_downv(x); if(sizev[cv[x][0]]+1 == p) return x; if(sizev[cv[x][0]] >= p) return find_rank(cv[x][0], p); else return find_rank(cv[x][1], p-sizev[cv[x][0]]-1);}void splay(LL x) { splayf(x); LL o = find_rank(p[rt], sizef[cf[x][0]]+1); splayv(o); p[x] = o;}void access(LL x) { LL tf = 0, tv = 0; while(x){ splay(x); LL o = p[x]; p[cf[x][1]] = cv[o][1]; cf[x][1] = tf; cv[o][1] = tv; if(tv) vfa[tv] = o; tv = o; tf = x; x = fa[x]; }}void make_root(LL x) { access(x); splay(x); revf[x] ^= 1; revv[p[x]] ^= 1; }void getchain(LL x, LL y) { make_root(x); access(y); splay(y); }LL getsum(LL x, LL y) { getchain(x, y); return sum[p[y]]; }LL getmin(LL x, LL y) { getchain(x, y); return Minn[p[y]]; }LL getmax(LL x, LL y) { getchain(x, y); return Maxx[p[y]]; }void add(LL x, LL y, LL c) { getchain(x, y); sum[p[y]] += sizev[p[y]]*c; val[p[y]] += c; Maxx[p[y]] += c; Minn[p[y]] += c; la[p[y]] += c; }void invert(LL x, LL y) { getchain(x, y); revv[p[y]] ^= 1; }int main() { LL i, j, k; Maxx[0] = -0x7fffffff; Minn[0] = 0x7fffffff; scanf("%lld%lld%lld", &n, &m, &r); for(i = 1; i < n; i++){ LL x, y; scanf("%lld%lld", &x, &y); ins(x, y); ins(y, x); } dfs(r); for(i = 1; i <= m; i++){ scanf("%s", s+1); if(s[1] == ‘I‘ && s[3] == ‘c‘){ LL x, y, c; scanf("%lld%lld%lld", &x, &y, &c); add(x, y, c); } else if(s[1] == ‘S‘){ LL x, y; scanf("%lld%lld", &x, &y); printf("%lld\n", getsum(x, y)); } else if(s[1] == ‘M‘ && s[2] == ‘a‘){ LL x, y; scanf("%lld%lld", &x, &y); printf("%lld\n", getmax(x, y)); } else if(s[1] == ‘M‘){ LL x, y; scanf("%lld%lld", &x, &y); printf("%lld\n", getmin(x, y)); } else { LL x, y; scanf("%lld%lld", &x, &y); invert(x, y); } } return 0;}
bzoj3159: 决战
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。