传送门:http://oj.cnuschool.org.cn/oj/home/problem.htm?problemID=983
WZJ的数据结构(七) |
难度级别:C; 运行时间限制:1000ms; 运行空间限制:51200KB; 代码长度限制:2000000B |
试题描述
|
给你一棵N个节点的无根树,每个点有一个权值(开始都是0)。请你设计一个数据结构,完成以下功能: 给你a、b、v,请将a到b路径中的节点权值都增加v(包括a点与b点)。最后输出每个节点的权值。
|
输入
|
第一行为一个正整数N。
接下来N-1行为每一条边,每行2个正整数a,b,表示有一条从a到b的边(从1开始编号)。 第N+1行为一个正整数Q,表示Q次操作。 接下来Q行为每一次询问,每行3个正整数a、b、v。 |
输出
|
最后输出每个点的权值,格式见样例。
|
输入示例
|
9 2 1 3 2 4 3 3 5 3 8 9 8 8 7 6 7 5 2 5 10 4 6 3 1 9 5 2 7 10 5 5 100 |
输出示例
|
5 25 28 3 110 3 13 18 5 |
其他说明
|
1<=N,Q<=100000
|
树链剖分版:
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<algorithm> 5 #include<queue> 6 #include<cstring> 7 #define PAU putchar(' ') 8 #define ENT putchar('\n') 9 using namespace std; 10 const int maxn=100000+10,inf=-1u>>1,maxn3=3*maxn; 11 struct Tedge{int x,y,w,next;}adj[maxn*2];int ms=0,fch[maxn]; 12 struct Edge{int from,to,dist;}e[maxn]; 13 void AddEdge(int u,int v,int w){adj[++ms]=(Tedge){u,v,w,fch[u]};fch[u]=ms;return;} 14 int top[maxn],dep[maxn],son[maxn],siz[maxn],fa[maxn],sumv[maxn3],addv[maxn3],num[maxn],sz=0,ql,qr,cv,_sum,n,Q; 15 void dfs(int u){ 16 siz[u]=1;dep[u]=dep[fa[u]]+1; 17 for(int i=fch[u];i;i=adj[i].next){ 18 int v=adj[i].y; 19 if(v!=fa[u]){ 20 fa[v]=u; 21 dfs(v); 22 if(siz[son[u]]<siz[v]) son[u]=v; 23 siz[u]+=siz[v]; 24 } 25 } return; 26 } 27 void build(int u,int tp){ 28 num[u]=++sz;top[u]=tp; 29 if(son[u]) build(son[u],tp); 30 for(int i=fch[u];i;i=adj[i].next){ 31 int v=adj[i].y; 32 if(v!=fa[u]&&v!=son[u]) build(v,v); 33 } return; 34 } 35 void update(int o,int L,int R){ 36 if(ql<=L&&R<=qr) addv[o]+=cv; 37 else{ 38 int M=L+R>>1,lc=o<<1,rc=lc|1; 39 if(ql<=M) update(lc,L,M); 40 if(qr>M) update(rc,M+1,R); 41 } return; 42 } 43 void change(int a,int b){ 44 _sum=0; 45 int f1=top[a],f2=top[b]; 46 while(f1!=f2){ 47 if(dep[f1]<dep[f2]) swap(f1,f2),swap(a,b); 48 ql=num[f1];qr=num[a];update(1,1,n); 49 a=fa[f1];f1=top[a]; 50 } 51 if(dep[a]>dep[b]) swap(a,b); 52 ql=num[a];qr=num[b];update(1,1,n);return;//为毛不是孩子了 53 } 54 void clear_set(int o,int L,int R,int add){ 55 if(L==R) sumv[L]+=add+addv[o]; 56 else{ 57 int M=L+R>>1,lc=o<<1,rc=lc|1; 58 clear_set(lc,L,M,add+addv[o]); 59 clear_set(rc,M+1,R,add+addv[o]); 60 } return; 61 } 62 inline int read(){ 63 int x=0,sig=1;char ch=getchar(); 64 while(!isdigit(ch)){if(ch=='-')sig=-1;ch=getchar();} 65 while(isdigit(ch))x=10*x+ch-'0',ch=getchar(); 66 return x*=sig; 67 } 68 inline void write(int x){ 69 if(x==0){putchar('0');return;}if(x<0)putchar('-'),x=-x; 70 int len=0,buf[15];while(x)buf[len++]=x%10,x/=10; 71 for(int i=len-1;i>=0;i--)putchar(buf[i]+'0');return; 72 } 73 void init(){ 74 n=read(); 75 for(int i=1;i<n;i++){ 76 int a=read(),b=read(); 77 AddEdge(a,b,0);AddEdge(b,a,0); 78 e[i]=(Edge){a,b,0}; 79 } 80 dfs(1);build(1,1); 81 for(int i=1;i<n;i++){ 82 if(dep[e[i].from]>dep[e[i].to]) swap(e[i].from,e[i].to); 83 } 84 return; 85 } 86 void work(){ 87 Q=read(); 88 while(Q--){ 89 int a=read(),b=read(),c=read(); 90 cv=c;change(a,b); 91 } 92 return; 93 } 94 void print(){ 95 clear_set(1,1,n,0); 96 for(int i=1;i<=n;i++){ 97 write(sumv[num[i]]);ENT; 98 } 99 return; 100 } 101 int main(){init();work();print();return 0;}
LCT
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<algorithm> 5 #include<queue> 6 #include<cstring> 7 #define PAU putchar(' ') 8 #define ENT putchar('\n') 9 using namespace std; 10 const int maxn=100000+10; 11 inline int read(){ 12 int x=0,sig=1;char ch=getchar(); 13 while(!isdigit(ch)){if(ch=='-')sig=-1;ch=getchar();} 14 while(isdigit(ch))x=10*x+ch-'0',ch=getchar(); 15 return x*=sig; 16 } 17 inline void write(int x){ 18 if(x==0){putchar('0');return;}if(x<0)putchar('-'),x=-x; 19 int len=0,buf[15];while(x)buf[len++]=x%10,x/=10; 20 for(int i=len-1;i>=0;i--)putchar(buf[i]+'0');return; 21 } 22 struct node { 23 node *ch[2],*fa; 24 bool rev; 25 int x,sum,siz,mul,add; 26 inline void add_rev_tag(){ 27 swap(ch[0],ch[1]);rev^=1;return; 28 } 29 inline void add_plus_tag(int a){ 30 sum+=siz*a;x+=a;add+=a;return; 31 } 32 inline void add_mul_tag(int m){ 33 sum*=m;x*=m;mul*=m;add*=add*m;return; 34 } 35 inline void down(){ 36 if(rev){ 37 if(ch[0]) ch[0]->add_rev_tag(); 38 if(ch[1]) ch[1]->add_rev_tag(); 39 rev=0; 40 } 41 if(add){ 42 if(ch[0]) ch[0]->add_plus_tag(add); 43 if(ch[1]) ch[1]->add_plus_tag(add); 44 add=0; 45 } 46 if(mul>1){ 47 if(ch[0]) ch[0]->add_mul_tag(mul); 48 if(ch[1]) ch[1]->add_mul_tag(mul); 49 mul=1; 50 } return; 51 } 52 inline void update(){ 53 sum=x;siz=1; 54 if(ch[0]) sum+=ch[0]->sum,siz+=ch[0]->siz; 55 if(ch[1]) sum+=ch[1]->sum,siz+=ch[1]->siz; 56 return; 57 } 58 }lct[maxn]; 59 inline int get_parent(node *x,node *&fa){return (fa=x->fa)?fa->ch[0]==x?0:fa->ch[1]==x?1:-1:-1;} 60 inline void rotate(node *x){ 61 int t1,t2; 62 node *fa,*gfa; 63 t1=get_parent(x,fa); 64 t2=get_parent(fa,gfa); 65 if ((fa->ch[t1]=x->ch[t1^1])) fa->ch[t1]->fa=fa; 66 x->ch[t1^1]=fa;fa->fa=x;x->fa=gfa; 67 if (t2!=-1) gfa->ch[t2]=x; 68 fa->update();return; 69 } 70 inline void pushdown(node *x){ 71 static node *stack[maxn]; 72 int cnt=0; 73 while(1){ 74 stack[cnt++]=x; 75 node *fa=x->fa; 76 if (!fa || (fa->ch[0]!=x && fa->ch[1]!=x)) break; 77 x=fa; 78 } 79 while(cnt--) stack[cnt]->down(); 80 return; 81 } 82 inline node * splay(node *x){ 83 pushdown(x); 84 while(1){ 85 int t1,t2; 86 node *fa,*gfa; 87 t1=get_parent(x,fa); 88 if(t1==-1) break; 89 t2=get_parent(fa,gfa); 90 if(t2==-1){ 91 rotate(x);break; 92 } else if (t1==t2){ 93 rotate(fa);rotate(x); 94 } else{ 95 rotate(x);rotate(x); 96 } 97 } 98 x->update(); 99 return x; 100 } 101 inline node * access(node *x){ 102 node *ret=NULL; 103 while (x) splay(x)->ch[1]=ret,(ret=x)->update(),x=x->fa; 104 return ret; 105 } 106 inline void makeroot(int x){access(lct+x)->add_rev_tag();} 107 inline void link(int u,int v){ 108 makeroot(u);splay(lct+u)->fa=lct+v;return; 109 } 110 inline void cut(int u,int v){ 111 makeroot(u); 112 node *p=(access(lct+v),splay(lct+v)); 113 p->ch[0]->fa=NULL; 114 p->ch[0]=NULL; 115 p->update(); 116 } 117 int n,q; 118 int main(){ 119 n=read(); 120 int i; 121 for(i=1;i<=n;i++) { 122 lct[i].x=lct[i].sum=0; 123 lct[i].siz=1; 124 lct[i].mul=1; 125 lct[i].add=0; 126 } 127 for(i=1;i<n;i++){ 128 int u,v; 129 u=read();v=read(); 130 link(u,v); 131 } 132 q=read();int x,y,c; 133 while(q--){ 134 x=read();y=read();c=read(); 135 makeroot(x);access(y+lct)->add_plus_tag(c); 136 } 137 for(int i=1;i<=n;i++) splay(i+lct),write(lct[i].x),ENT; 138 /*while(q--){ 139 char ch=getchar(); 140 while(ch<=32) ch=getchar(); 141 int u,v,x,y,c; 142 if(ch=='+'){ 143 u=read();v=read();c=read(); 144 makeroot(u); 145 access(lct+v)->add_plus_tag(c); 146 }else if(ch=='-'){ 147 u=read();v=read();x=read();y=read(); 148 cut(u,v);link(x,y); 149 }else if(ch=='*'){ 150 u=read();v=read();c=read(); 151 makeroot(u); 152 access(lct+v)->add_mul_tag(c); 153 }else if(ch=='/'){ 154 u=read();v=read(); 155 makeroot(u); 156 printf("%u\n",access(lct+v)->sum); 157 } 158 }*/ 159 return 0; 160 }