Snacks
题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=5692
dfs序+线段树
这道题涉及到对整棵树的值修改,考虑将树状结构用dfs序转化成线性结构,将树的修改转化为区间修改以降低时间复杂度(之前组队赛的时候遇到一道类似的没调出来...代码能力太缺乏了...)
代码如下:
1 #include<cstdio> 2 #include<vector> 3 #include<iostream> 4 #include<cstring> 5 #pragma comment(linker, "/STACK:1024000000,1024000000") 6 #define LL long long 7 #define N 100100 8 #define lson (x<<1) 9 #define rson (x<<1|1) 10 #define mid ((l+r)>>1) 11 using namespace std; 12 struct node{ 13 LL sum,lazy; 14 }a[N<<2]; 15 LL val[N]; 16 int L[N],R[N]; 17 LL spre[N]; 18 int index; 19 bool vis[N]; 20 vector<int>e[N]; 21 void init(){ 22 //for(int i=0;i<N;++i)e[i].clear(); 23 //memset(a,0,sizeof(a)); 24 memset(vis,0,sizeof(vis)); 25 memset(L,0,sizeof(L)); 26 memset(R,0,sizeof(R)); 27 memset(val,0,sizeof(val)); 28 memset(spre,0,sizeof(spre)); 29 index=0; 30 } 31 void dfs(int num,LL v){ 32 vis[num]=1; 33 ++index; 34 L[num]=index; 35 for(LL i=0;i<e[num].size();i++) 36 if(!vis[e[num][i]])dfs(e[num][i],v+val[e[num][i]]); 37 e[num].clear(); 38 spre[L[num]]=v; 39 R[num]=index; 40 } 41 void push_up(int x){ 42 a[x].sum=max(a[lson].sum,a[rson].sum); 43 } 44 void push_down(int x){ 45 a[rson].sum+=a[x].lazy; 46 a[rson].lazy+=a[x].lazy; 47 a[lson].sum+=a[x].lazy; 48 a[lson].lazy+=a[x].lazy; 49 a[x].lazy=0; 50 } 51 void build(int x,int l,int r){ 52 a[x].lazy=a[x].sum=0; 53 if(l==r){ 54 a[x].sum=spre[l]; 55 return; 56 } 57 build(lson,l,mid); 58 build(rson,mid+1,r); 59 push_up(x); 60 } 61 void add(int x,int l,int r,int cl,int cr,LL v){ 62 if(cl<=l&&r<=cr){ 63 a[x].sum+=v; 64 a[x].lazy+=v; 65 return; 66 } 67 if(a[x].lazy!=0)push_down(x);/**except this!!!**/ 68 if(cl<=mid)add(lson,l,mid,cl,cr,v); 69 if(mid<cr)add(rson,mid+1,r,cl,cr,v); 70 push_up(x); 71 } 72 LL query(int x,int l,int r,int ql,int qr){ 73 if(ql<=l&&r<=qr)return a[x].sum; 74 if(a[x].lazy!=0)push_down(x); 75 LL temp=-(LL)1000000000000000000; 76 if(ql<=mid)temp=max(temp,query(lson,l,mid,ql,qr)); 77 if(mid<qr)temp=max(temp,query(rson,mid+1,r,ql,qr)); 78 return temp; 79 } 80 int main(void){ 81 int T,n,m; 82 scanf("%d",&T); 83 for(int i=1;i<=T;++i){ 84 /*if(i==10)while(1); 85 WA when i==10*/ 86 init(); 87 scanf("%d%d",&n,&m); 88 for(int j=1;j<n;++j){ 89 int x,y; 90 scanf("%d%d",&x,&y);x++,y++; 91 e[x].push_back(y); 92 e[y].push_back(x); 93 } 94 for(int j=1;j<=n;++j) 95 scanf("%I64d",&val[j]); 96 dfs(1,val[1]); 97 build(1,1,n); 98 printf("Case #%d: ",i); 99 while(m--){ 100 int type; 101 scanf("%d",&type); 102 if(type==0){ 103 int x,v; 104 scanf("%d%d",&x,&v);x++; 105 LL diff=(LL)v-val[x]; 106 val[x]=(LL)v; 107 add(1,1,n,L[x],R[x],diff); 108 }else if(type==1){ 109 int x; 110 scanf("%d",&x);x++; 111 LL temp=query(1,1,n,L[x],R[x]); 112 printf("%I64d ",temp); 113 } 114 } 115 } 116 return 0; 117 }