首页 > 代码库 > Bzoj4034 [HAOI2015]T2
Bzoj4034 [HAOI2015]T2
Time Limit: 10 Sec Memory Limit: 256 MB
Submit: 3477 Solved: 1085
Description
有一棵点数为 N 的树,以点 1 为根,且树点有边权。然后有 M 个
操作,分为三种:
操作 1 :把某个节点 x 的点权增加 a 。
操作 2 :把某个节点 x 为根的子树中所有点的点权都增加 a 。
操作 3 :询问某个节点 x 到根的路径中所有点的点权和。
Input
第一行包含两个整数 N, M 。表示点数和操作数。
接下来一行 N 个整数,表示树中节点的初始权值。
接下来 N-1 行每行三个正整数 fr, to , 表示该树中存在一条边 (fr, to) 。
再接下来 M 行,每行分别表示一次操作。其中第一个数表示该操
作的种类( 1-3 ) ,之后接这个操作的参数( x 或者 x a ) 。
Output
对于每个询问操作,输出该询问的答案。答案之间用换行隔开。
Sample Input
5 5
1 2 3 4 5
1 2
1 4
2 3
2 5
3 3
1 2 1
3 5
2 1 2
3 3
1 2 3 4 5
1 2
1 4
2 3
2 5
3 3
1 2 1
3 5
2 1 2
3 3
Sample Output
6
9
13
9
13
HINT
对于 100% 的数据, N,M<=100000 ,且所有输入数据的绝对值都不会超过 10^6 。
Source
鸣谢bhiaibogf提供
树链剖分裸题
1 /*by SilverN*/ 2 #include<iostream> 3 #include<algorithm> 4 #include<cstring> 5 #include<cstdio> 6 #include<cmath> 7 #define ls l,mid,rt<<1 8 #define rs mid+1,r,rt<<1|1 9 #define LL long long 10 using namespace std; 11 const int mxn=100010; 12 int read(){ 13 int x=0,f=1;char ch=getchar(); 14 while(ch<‘0‘ || ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();} 15 while(ch>=‘0‘ && ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();} 16 return x*f; 17 } 18 int n,m; 19 struct edge{ 20 int v,nxt; 21 }e[mxn<<1]; 22 int hd[mxn],mct=0; 23 void add_edge(int u,int v){ 24 e[++mct].v=v;e[mct].nxt=hd[u];hd[u]=mct;return; 25 } 26 struct node{ 27 int w,e; 28 int top,f,son; 29 int size,dep; 30 }tr[mxn]; 31 struct segtree{ 32 LL sum,mk; 33 }st[mxn<<2]; 34 int sz=0; 35 int w[mxn]; 36 void DFS1(int u){ 37 tr[u].size=1;tr[u].son=0; 38 for(int i=hd[u];i;i=e[i].nxt){ 39 int v=e[i].v; 40 if(v==tr[u].f)continue; 41 tr[v].f=u; 42 tr[v].dep=tr[u].dep+1; 43 DFS1(v); 44 tr[u].size+=tr[v].size; 45 if(tr[v].size>tr[tr[u].son].size)tr[u].son=v; 46 } 47 return; 48 } 49 void DFS2(int u,int top){ 50 tr[u].top=top; 51 tr[u].w=++sz; 52 if(tr[u].son){ 53 DFS2(tr[u].son,top); 54 for(int i=hd[u];i;i=e[i].nxt){ 55 int v=e[i].v; 56 if(v!=tr[u].f && v!=tr[u].son){ 57 DFS2(v,v); 58 } 59 } 60 } 61 tr[u].e=sz; 62 return; 63 } 64 void pushdown(int l,int r,int rt){ 65 if(l==r)return; 66 st[rt<<1].mk+=st[rt].mk;st[rt<<1|1].mk+=st[rt].mk; 67 int mid=(l+r)>>1; 68 st[rt<<1].sum+=st[rt].mk*(mid-l+1); 69 st[rt<<1|1].sum+=st[rt].mk*(r-mid); 70 st[rt].mk=0; 71 return; 72 } 73 void add(int L,int R,int v,int l,int r,int rt){ 74 if(L<=l && r<=R){ 75 st[rt].sum+=(LL)v*(r-l+1); 76 st[rt].mk+=v; 77 return; 78 } 79 if(st[rt].mk)pushdown(l,r,rt); 80 int mid=(l+r)>>1; 81 if(L<=mid)add(L,R,v,ls); 82 if(R>mid)add(L,R,v,rs); 83 st[rt].sum=st[rt<<1].sum+st[rt<<1|1].sum; 84 return; 85 } 86 long long qsum(int L,int R,int l,int r,int rt){ 87 if(L<=l && r<=R)return st[rt].sum; 88 if(st[rt].mk)pushdown(l,r,rt); 89 int mid=(l+r)>>1; 90 LL res=0; 91 if(L<=mid)res+=qsum(L,R,ls); 92 if(R>mid)res+=qsum(L,R,rs); 93 return res; 94 } 95 long long findsum(int x){ 96 LL res=0; 97 while(tr[x].top!=1){ 98 res+=qsum(tr[tr[x].top].w,tr[x].w,1,n,1); 99 x=tr[tr[x].top].f;100 }101 res+=qsum(1,tr[x].w,1,n,1);102 return res;103 }104 int main(){105 n=read();m=read();106 int i,j,u,v,op,x,a;107 for(i=1;i<=n;i++)w[i]=read();108 for(i=1;i<n;i++){109 u=read();v=read();110 add_edge(u,v);111 add_edge(v,u);112 }113 DFS1(1);114 DFS2(1,1);115 for(i=1;i<=n;i++)116 add(tr[i].w,tr[i].w,w[i],1,n,1);117 /* for(i=1;i<=n;i++)118 printf("%d ",qsum(tr[i].w,tr[i].w,1,n,1));119 printf("\n");*/120 for(i=1;i<=m;i++){121 op=read();122 switch(op){123 case 1:{124 x=read();a=read();125 add(tr[x].w,tr[x].w,a,1,n,1);126 break;127 }128 case 2:{129 x=read();a=read();130 add(tr[x].w,tr[x].e,a,1,n,1);131 break;132 }133 case 3:{134 x=read();135 printf("%lld\n",findsum(x));136 break;137 }138 }139 }140 return 0;141 }
Bzoj4034 [HAOI2015]T2
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。