[ZJOI2008] 树的统计

洛谷 P2590 传送门

bzoj 1036 传送门

感觉最近有点虚,码个板子爽一下。

居然没一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
",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
",ans);
154         }
155     }
156     return 0;
157 }
原文地址:https://www.cnblogs.com/eternhope/p/9909650.html