转存
作者:互联网
#include <bits/stdc++.h> #define endl putchar('\n') #define lson(x) tree[x].ch[0] #define rson(x) tree[x].ch[1] #define siz(x) tree[x].size #define fa(x) tree[x].fa #define lazy(rt) tree[rt].lazy #define sum(x) tree[x].sum #define val(x) tree[x].val #define flag printf("----------\n"); using namespace std; const int M =1e6+10; const int inf = 2147483647; struct Splay{ int ch[2]; int val,fa,cnt,size,lazy,sum; }; Splay tree[M];int root,tot; int tag[M]; inline int read(){ int x=0,f=0;char c=getchar(); while(!isdigit(c)){ if(c=='-') f=1;c=getchar(); } do{ x=(x<<1)+(x<<3)+(c^48); }while(isdigit(c=getchar())); return f?-x:x; } inline void print(int x){ if(x<0) putchar('-'),x=-x; if(x>9) print(x/10);putchar(x%10^48); } void update(int rt){ siz(rt)=siz(lson(rt))+siz(rson(rt))+1;//!! sum(rt)=sum(lson(rt))+sum(rson(rt))+val(rt); } void pushdown(int rt){ if(lazy(rt)){ if(lson(rt)){ sum(lson(rt))+=lazy(rt)*siz(lson(rt)); val(lson(rt))+=tag[lson(rt)]*lazy(rt); lazy(lson(rt))+=lazy(rt); } if(rson(rt)){ sum(rson(rt))+=lazy(rt)*siz(rson(rt)); val(rson(rt))+=tag[rson(rt)]*lazy(rt); lazy(rson(rt))+=lazy(rt); } } } bool which(int rt){ return (rson(fa(rt))==rt); } void link(int rt,int fa,int op){ tree[fa].ch[op]=rt; fa(rt)=fa; } void twist(int rt){ int fa=fa(rt),grand=fa(fa); int op1=which(rt),op2=which(fa); pushdown(fa);pushdown(rt); link(rt,grand,op2); link(tree[rt].ch[op1^1],fa,op1); link(fa,rt,(op1^1)); update(fa);update(rt); } void splay(int rt,int to){ while(fa(rt)!=to){ if(fa(fa(rt))!=to) twist((which(rt)==which(fa(rt)))?fa(rt):rt); twist(rt); } if(!to) root=rt; } int dfn[M],a[M],n,tim=1; vector <int> vec[M]; void dfs(int u){ dfn[++tim]=u; for(int i=0;i<vec[u].size();i++) dfs(vec[u][i]); dfn[++tim]=u+n; } int build(int l,int r,int fa){ if(l>r) return 0; int mid=(l+r)>>1,now=dfn[mid];//二分建完美树 fa(now)=fa; lson(now)=build(l,mid-1,now); rson(now)=build(mid+1,r,now); val(now)=(now<=n)?a[now]:-a[now]; update(now); return now; } int pre(int x){ splay(x,0); int now=lson(x); while(rson(now)) now=rson(now); return now; } int down(int x){ splay(x,0); int now=rson(x); while(lson(x)) now=lson(x); return now; } void change(int x,int y){//change x to y int p=pre(x),q=down(x+n); splay(p,0);splay(q,p); int o=lson(q); fa(lson(q))=0;lson(q)=0; update(rson(root));update(root); q=down(y); splay(y,0);splay(q,y); fa(o)=q;lson(q)=o; update(rson(root));update(root); } int asksum(int x){ int p=n*2+1,q=down(x); splay(p,0);splay(q,p); return sum(lson(q)); } void add(int x,int y){ int p=pre(x),q=down(x+n); splay(p,0);splay(q,p); lazy(lson(q))+=y; sum(lson(q))+=y*siz(lson(q)); val(lson(q))+=tag[lson(q)]*y; } int main(){ n=read(); for(int i=2;i<=n;i++){ int x=read(); vec[x].push_back(i); } for(int i=1;i<=n;i++){ a[i]=read();tag[i]=1,tag[i+n]=-1; } dfn[1]=n*2+1; dfs(1); dfn[++tim]=n*2+2; root=build(1,tim,0); int t=read(); while(t--){ char op=getchar();while(!isalpha(op)) op=getchar(); int x,y; if(op=='Q') x=read(),print(asksum(x)),endl; if(op=='C') x=read(),y=read(),change(x,y); if(op=='F') x=read(),y=read(),add(x,y); } return 0; } /* #include<iostream> #include<cstring> #include<cstdio> #define N (200009) #define LL long long using namespace std; struct Edge{int to,next;}edge[N<<1]; int n,m,x,y,Root,q[N],q_num; int head[N],num_edge; int Son[N][2],Father[N]; int a[N],Flag[N]; LL Num[N],Sum[N],Val[N],Add[N]; char opt; inline int read() { int x=0; char c=getchar(); while (c<'0' || c>'9') c=getchar(); while (c>='0' && c<='9') x=x*10+c-'0', c=getchar(); return x; } void add(int u,int v) { edge[++num_edge].to=v; edge[num_edge].next=head[u]; head[u]=num_edge; } int Get(int x) {return Son[Father[x]][1]==x;} void Pushup(int x) { Num[x]=Num[Son[x][0]]+Num[Son[x][1]]+Flag[x]; Sum[x]=Sum[Son[x][0]]+Sum[Son[x][1]]+Val[x]; } void Pushdown(int x) { if (Add[x]) { int ls=Son[x][0], rs=Son[x][1]; Sum[ls]+=Add[x]*Num[ls]; Val[ls]+=Flag[ls]*Add[x]; Add[ls]+=Add[x]; Sum[rs]+=Add[x]*Num[rs]; Val[rs]+=Flag[rs]*Add[x]; Add[rs]+=Add[x]; Add[x]=0; } } void Rotate(int x) { int wh=Get(x); int fa=Father[x],fafa=Father[fa]; Pushdown(fa); Pushdown(x); if (fafa) Son[fafa][Son[fafa][1]==fa]=x; Son[fa][wh]=Son[x][wh^1]; Father[fa]=x; if (Son[fa][wh]) Father[Son[fa][wh]]=fa; Son[x][wh^1]=fa; Father[x]=fafa; Pushup(fa); Pushup(x); } void Splay(int x,int tar) { for (int fa; (fa=Father[x])!=tar; Rotate(x)) if (Father[fa]!=tar) Rotate(Get(fa)==Get(x)?fa:x); if (!tar) Root=x; } int Pre(int x) { Splay(x,0); int now=Son[x][0]; while (Son[now][1]) now=Son[now][1]; return now; } int Next(int x) { Splay(x,0); int now=Son[x][1]; while (Son[now][0]) now=Son[now][0]; return now; } void Query(int x) { int pre=n<<1|1, nxt=Next(x); Splay(pre,0); Splay(nxt,pre); printf("%lld\n",Sum[Son[nxt][0]]); } void Change(int x,int y) { int pre=Pre(x),nxt=Next(x+n); Splay(pre,0); Splay(nxt,pre); int tmp=Son[nxt][0]; Father[Son[nxt][0]]=0; Son[nxt][0]=0; Pushup(Son[Root][1]); Pushup(Root); int Nxt=Next(y); Splay(y,0); Splay(Nxt,y); Father[tmp]=Nxt; Son[Nxt][0]=tmp; Pushup(Son[Root][0]); Pushup(Root); } void Update(int x,int y) { int pre=Pre(x), nxt=Next(x+n); Splay(pre,0); Splay(nxt,pre); int tmp=Son[nxt][0]; Add[tmp]+=y; Sum[tmp]+=Add[tmp]*Num[tmp]; Val[tmp]+=Flag[tmp]*Add[tmp]; } void DFS(int x,int fa) { q[++q_num]=x; for (int i=head[x]; i; i=edge[i].next) if (edge[i].to!=fa) DFS(edge[i].to,x); q[++q_num]=x+n; } int Build(int l,int r,int fa) { if (l>r) {return 0;} int mid=(l+r)>>1, now=q[mid]; Father[now]=fa; Son[now][0]=Build(l,mid-1,now); Son[now][1]=Build(mid+1,r,now); Val[now]=(now<=n)?a[now]:-a[now-n]; Pushup(now); return now; } int main() { n=read(); for (int i=2; i<=n; ++i) x=read(), add(x,i); for (int i=1; i<=n; ++i) a[i]=read(), Flag[i]=1, Flag[i+n]=-1; q[q_num=1]=n<<1|1; DFS(1,0); q[++q_num]=n+1<<1; Root=Build(1,q_num,0); m=read(); for (int i=1; i<=m; ++i) { opt=getchar(); while (opt<'A' || opt>'Z') opt=getchar(); if (opt=='Q') x=read(), Query(x); if (opt=='C') x=read(), y=read(), Change(x,y); if (opt=='F') x=read(), y=read(), Update(x,y); } } */
标签:rt,lazy,int,rson,fa,now,转存 来源: https://www.cnblogs.com/blue-tsg/p/16388090.html