[ZJOI2008] 树的统计
感觉最近有点虚,码个板子爽一下。
居然没一A,交了两遍才A......
其原因是定义qmx函数的时候我懒得重敲一遍,直接把qsum那个复制过来改了一下。
然后忘把qsum(p<<1,l,r)和qsum(p<<1|1,l,r)改成qmx了。
这样的话只要是qmx操作,第一遍还是qmx,分治到两边就变成qsum了......
代码:
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 6 int n,q; 7 int hd[30005],to[60005],nx[60005],ec; 8 int bv[30005]; 9 10 void edge(int af,int at) 11 { 12 to[++ec]=at; 13 nx[ec]=hd[af]; 14 hd[af]=ec; 15 } 16 17 int f[30005],dep[30005],tp[30005]; 18 int sz[30005],son[30005]; 19 int in[30005],out[30005],pc,pos[30005]; 20 21 void pre(int p,int fa) 22 { 23 f[p]=fa; 24 dep[p]=dep[fa]+1; 25 sz[p]=1; 26 for(int i=hd[p];i;i=nx[i]) 27 { 28 if(to[i]==fa)continue; 29 pre(to[i],p); 30 sz[p]+=sz[to[i]]; 31 if(sz[son[p]]<sz[to[i]])son[p]=to[i]; 32 } 33 } 34 35 void dfs(int p) 36 { 37 in[p]=++pc; 38 pos[pc]=p; 39 if(p==son[f[p]])tp[p]=tp[f[p]]; 40 else tp[p]=p; 41 if(son[p])dfs(son[p]); 42 for(int i=hd[p];i;i=nx[i]) 43 if(to[i]!=f[p]&&to[i]!=son[p])dfs(to[i]); 44 out[p]=pc; 45 } 46 47 int sum[120005],mx[120005],lb[120005],rb[120005]; 48 49 void pushup(int p) 50 { 51 sum[p]=sum[p<<1]+sum[p<<1|1]; 52 mx[p]=max(mx[p<<1],mx[p<<1|1]); 53 } 54 55 void build(int p,int l,int r) 56 { 57 lb[p]=l,rb[p]=r; 58 if(l==r) 59 { 60 mx[p]=sum[p]=bv[pos[l]]; 61 return; 62 } 63 int mid=(l+r)>>1; 64 build(p<<1,l,mid); 65 build(p<<1|1,mid+1,r); 66 pushup(p); 67 } 68 69 void change(int p,int pnt,int v) 70 { 71 if(lb[p]==rb[p]) 72 { 73 sum[p]=mx[p]=v; 74 return; 75 } 76 int mid=(lb[p]+rb[p])>>1; 77 if(pnt<=mid)change(p<<1,pnt,v); 78 else change(p<<1|1,pnt,v); 79 pushup(p); 80 } 81 82 int qsum(int p,int l,int r) 83 { 84 if(lb[p]>=l&&rb[p]<=r)return sum[p]; 85 int ret=0,mid=(lb[p]+rb[p])>>1; 86 if(l<=mid)ret+=qsum(p<<1,l,r); 87 if(r>mid)ret+=qsum(p<<1|1,l,r); 88 return ret; 89 } 90 91 int qmx(int p,int l,int r) 92 { 93 if(lb[p]>=l&&rb[p]<=r)return mx[p]; 94 int ret=-0x3f3f3f3f,mid=(lb[p]+rb[p])>>1; 95 if(l<=mid)ret=max(qmx(p<<1,l,r),ret); 96 if(r>mid)ret=max(qmx(p<<1|1,l,r),ret); 97 return ret; 98 } 99 100 int main() 101 { 102 scanf("%d",&n); 103 for(int i=1;i<n;i++) 104 { 105 int ff,tt; 106 scanf("%d%d",&ff,&tt); 107 edge(ff,tt); 108 edge(tt,ff); 109 } 110 for(int i=1;i<=n;i++)scanf("%d",&bv[i]); 111 pre(1,1); 112 dfs(1); 113 build(1,1,n); 114 scanf("%d",&q); 115 while(q--) 116 { 117 char op[15]; 118 scanf("%s",op+1); 119 if(op[2]=='H') 120 { 121 int u,t; 122 scanf("%d%d",&u,&t); 123 change(1,in[u],t); 124 } 125 if(op[2]=='M') 126 { 127 int x,y; 128 scanf("%d%d",&x,&y); 129 int ans=-0x3f3f3f3f; 130 while(tp[x]!=tp[y]) 131 { 132 if(dep[tp[x]]<dep[tp[y]])swap(x,y); 133 ans=max(qmx(1,in[tp[x]],in[x]),ans); 134 x=f[tp[x]]; 135 } 136 if(dep[x]>dep[y])swap(x,y); 137 ans=max(qmx(1,in[x],in[y]),ans); 138 printf("%d\n",ans); 139 } 140 if(op[2]=='S') 141 { 142 int x,y; 143 scanf("%d%d",&x,&y); 144 int ans=0; 145 while(tp[x]!=tp[y]) 146 { 147 if(dep[tp[x]]<dep[tp[y]])swap(x,y); 148 ans+=qsum(1,in[tp[x]],in[x]); 149 x=f[tp[x]]; 150 } 151 if(dep[x]>dep[y])swap(x,y); 152 ans+=qsum(1,in[x],in[y]); 153 printf("%d\n",ans); 154 } 155 } 156 return 0; 157 }