ll卡了我半个小时
1 #include<bits/stdc++.h> 2 #define lowbit(a) ((a)&(-(a))) 3 #define l(a) ((a)<<1) 4 #define r(a) ((a)<<1|1) 5 #define clr(a,x) memset(a,x,sizeof(a)) 6 #define rep(i,l,r) for(int i=l;i<(r);i++) 7 #define Rep(i,a) rep(i,0,e[a].size()) 8 typedef long long ll; 9 using namespace std; 10 int read() 11 { 12 char c=getchar(); 13 int ans=0,f=1; 14 while(!isdigit(c)){ 15 if(c=='-') f=-1; 16 c=getchar(); 17 } 18 while(isdigit(c)){ 19 ans=ans*10+c-'0'; 20 c=getchar(); 21 } 22 return ans*f; 23 } 24 struct node{ 25 ll l,r,sum,add; 26 }; 27 const int maxn=100009,inf=0x3fffffff; 28 int n,m,dfstime=0,w[maxn],f[maxn],son[maxn],top[maxn],dep[maxn],id[maxn],idr[maxn],L[maxn],R[maxn],size[maxn]; 29 node x[maxn<<2]; 30 vector<int>e[maxn]; 31 void dfs(int k){ 32 size[k]=1; 33 Rep(i,k){ 34 int to=e[k][i]; 35 if(to==f[k]) continue; 36 dep[to]=dep[k]+1; 37 f[to]=k; 38 dfs(to); 39 size[k]+=size[to]; 40 if(!son[k]||size[son[k]]<size[to]) son[k]=to; 41 } 42 } 43 int Top; 44 void Dfs(int k){ 45 top[k]=Top; 46 L[k]=id[k]=++dfstime; 47 idr[id[k]]=k; 48 if(son[k]) Dfs(son[k]); 49 Rep(i,k){ 50 int to=e[k][i]; 51 if(id[to]) continue; 52 Dfs(Top=to); 53 } 54 R[k]=dfstime; 55 } 56 void maintain(int k){ 57 x[k].sum=x[l(k)].sum+x[r(k)].sum; 58 } 59 void pushdown(int k){ 60 if(x[k].l==x[k].r){ 61 x[k].add=0; 62 return; 63 } 64 if(!x[k].add) return; 65 x[l(k)].sum+=(x[l(k)].r-x[l(k)].l+1)*x[k].add; 66 x[r(k)].sum+=(x[r(k)].r-x[r(k)].l+1)*x[k].add; 67 x[l(k)].add+=x[k].add; 68 x[r(k)].add+=x[k].add; 69 x[k].add=0; 70 } 71 void modify(int k,int l,int r,int t){ 72 pushdown(k); 73 if(x[k].l==l&&x[k].r==r){ 74 x[k].add+=t; 75 x[k].sum+=(ll)(r-l+1)*t; 76 return; 77 } 78 int mid=(x[k].l+x[k].r)>>1; 79 if(r<=mid) modify(l(k),l,r,t); 80 else if(l>mid) modify(r(k),l,r,t); 81 else{ 82 modify(l(k),l,mid,t); 83 modify(r(k),mid+1,r,t); 84 } 85 maintain(k); 86 } 87 ll ask(int k,int l,int r){ 88 pushdown(k); 89 if(x[k].l==l&&x[k].r==r) return x[k].sum; 90 int mid=(x[k].l+x[k].r)>>1; 91 if(r<=mid) return ask(l(k),l,r); 92 if(l>mid) return ask(r(k),l,r); 93 return ask(l(k),l,mid)+ask(r(k),mid+1,r); 94 } 95 void build(int k,int l,int r){ 96 x[k].l=l;x[k].r=r;x[k].add=0; 97 if(l==r){ 98 x[k].sum=w[idr[l]]; 99 return; 100 } 101 int mid=(l+r)>>1; 102 build(l(k),l,mid); 103 build(r(k),mid+1,r); 104 maintain(k); 105 } 106 void addnode(int u,int t){ 107 modify(1,id[u],id[u],t); 108 } 109 void addtree(int u,int t){ 110 modify(1,L[u],R[u],t); 111 } 112 ll asksum(int u,int v){ 113 ll ans=0; 114 while(top[u]!=top[v]){ 115 if(dep[top[u]]<dep[top[v]]) swap(u,v); 116 ans+=ask(1,id[top[u]],id[u]); 117 u=f[top[u]]; 118 } 119 if(dep[u]>dep[v]) swap(u,v); 120 ans+=ask(1,id[u],id[v]); 121 return ans; 122 } 123 void init(){ 124 dfs(1); 125 Dfs(Top=1); 126 build(1,1,n); 127 } 128 int main() 129 { 130 freopen("test.in","r",stdin); 131 freopen("my.out","w",stdout); 132 n=read(),m=read(); 133 rep(i,1,n+1) w[i]=read(); 134 rep(i,1,n){ 135 int from=read(),to=read(); 136 e[from].push_back(to); 137 e[to].push_back(from); 138 } 139 init(); 140 while(m--){ 141 int opt=read(),u=read(),v; 142 if(opt!=3) v=read(); 143 if(opt==1) addnode(u,v); 144 else if(opt==2) addtree(u,v); 145 else printf("%lld ",asksum(1,u)); 146 } 147 return 0; 148 }
4034: [HAOI2015]T2
Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 681 Solved: 253
[Submit][Status][Discuss]
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 。