[ZJOI2008]树的统计

   树剖+线段树

   据说是入门题,然而蒟蒻没有做过。

  1 #include<bits/stdc++.h>
  2 #define re register int
  3 #define maxn 100000+5
  4 #define inf 1000000000
  5 #define lson now<<1
  6 #define rson now<<1|1
  7 using namespace std;
  8 inline int read()
  9 {
 10     int x=0,f=1; 
 11     char ch=getchar();
 12     while(!isdigit(ch))
 13    {
 14        if(ch=='-') f=-1;
 15     ch=getchar();
 16 }
 17     while(isdigit(ch))
 18     {
 19         x=x*10+ch-'0';
 20         ch=getchar();
 21     }
 22     return x*f;
 23 }
 24 inline void write(int x)
 25 {
 26     if(x<0) putchar('-'),x=-x;
 27     if(x>9) write(x/10);
 28     putchar(x%10+'0');
 29 }
 30 int dep[maxn],siz[maxn],son[maxn],fa[maxn];
 31 int id[maxn],rnk[maxn],top[maxn],val[maxn];
 32 int n;
 33 struct edge{
 34     int nex,to; 
 35 }ed[maxn<<1];
 36 int head[maxn];
 37 struct tree{
 38     int sum,maxw; 
 39 }tr[maxn<<2];
 40 void pushup(int now)
 41 {
 42     tr[now].sum=tr[lson].sum+tr[rson].sum;
 43     tr[now].maxw=max(tr[lson].maxw,tr[rson].maxw);
 44 }
 45 void build(int now,int l,int r)
 46 {
 47     if(l==r)
 48     {
 49         tr[now].sum=tr[now].maxw=val[rnk[l]];
 50         return;
 51     }
 52     int mid=(l+r)>>1; 
 53     build(lson,l,mid);
 54     build(rson,mid+1,r);
 55     pushup(now); 
 56 }
 57 int qsum(int ql,int qr,int l,int r,int now)
 58 {
 59     if(l>=ql&&r<=qr) return tr[now].sum;
 60     int mid=(l+r)>>1,res=0;
 61     if(ql<=mid)  res+=qsum(ql,qr,l,mid,lson);
 62     if(qr>mid)  res+=qsum(ql,qr,mid+1,r,rson);
 63     return res;
 64 }
 65 int qmax(int ql,int qr,int l,int r,int now)
 66 {
 67     if(l>=ql&&r<=qr) return tr[now].maxw;
 68     int mid=(l+r)>>1;
 69     int Max=-inf;
 70     if(ql<=mid) Max=max(Max,qmax(ql,qr,l,mid,lson));
 71     if(qr>mid) Max=max(Max,qmax(ql,qr,mid+1,r,rson)); 
 72     return Max;
 73 }
 74 void update(int l,int r,int now,int ch,int w)
 75 {
 76     if(l==r)
 77     {
 78     tr[now].sum=tr[now].maxw=w;
 79     return;
 80     }
 81     int mid=(l+r)>>1;
 82     if(ch<=mid)
 83     update(l,mid,lson,ch,w);
 84     else 
 85     update(mid+1,r,rson,ch,w);
 86     pushup(now);
 87 }
 88 int cnt,num,q;
 89 void add(int x,int y)
 90 {
 91     ed[++cnt].nex=head[x];
 92     ed[cnt].to=y;
 93     head[x]=cnt;
 94 }
 95 void dfs(int pos,int f)
 96 {
 97     fa[pos]=f;
 98     dep[pos]=dep[f]+1;
 99     siz[pos]=1;
100     for(re i=head[pos];i;i=ed[i].nex) 
101     {
102         if(ed[i].to!=f){
103             dfs(ed[i].to,pos);
104             siz[pos]+=siz[ed[i].to];
105             if(siz[ed[i].to]>siz[son[pos]]) 
106             son[pos]=ed[i].to;
107         }
108     }
109 }
110 void dfs2(int pos,int tp)
111 {
112     top[pos]=tp;
113     id[pos]=++num;
114     rnk[num]=pos;
115     if(son[pos]) dfs2(son[pos],tp);
116     for(re i=head[pos];i;i=ed[i].nex)
117         if(ed[i].to!=fa[pos]&&ed[i].to!=son[pos])
118         dfs2(ed[i].to,ed[i].to);
119 }
120 int qqsum(int x,int y)
121 {
122     int res=0;
123     while(top[x]!=top[y]){
124     if(dep[top[x]]<dep[top[y]]) swap(x,y);
125     res+=qsum(id[top[x]],id[x],1,n,1);
126     x=fa[top[x]]; 
127 }
128      if(dep[x]>dep[y]) swap(x,y);
129      res+=qsum(id[x],id[y],1,n,1);
130      return res;
131 }
132 int qqmax(int x,int y)
133 {
134     int Max=-inf;
135     while(top[x]!=top[y]){
136     if(dep[top[x]]<dep[top[y]]) swap(x,y);
137     Max=max(Max,qmax(id[top[x]],id[x],1,n,1));
138     x=fa[top[x]]; 
139 }
140      if(dep[x]>dep[y]) swap(x,y);
141      Max=max(Max,qmax(id[x],id[y],1,n,1));
142      return Max;
143 }
144 int main()
145 {
146     n=read();
147     for(re i=1;i<=n-1;i++)
148     {
149         int x,y;
150         x=read();
151         y=read();
152         add(x,y);
153         add(y,x);
154     }
155     for(re i=1;i<=n;i++)
156     val[i]=read();
157     dfs(1,0);
158     dfs2(1,1);
159     build(1,1,n);
160     q=read();
161     char s[10];
162     while(q--)
163     {
164         int x,y;
165         cin>>s;
166         x=read();
167         y=read();
168         if(s[0]=='C') update(1,n,1,id[x],y);
169         else if(s[1]=='M')
170         {
171             write(qqmax(x,y));
172             putchar('
');
173         }
174         else{
175             write(qqsum(x,y));
176             putchar('
');
177         }
178     }
179     return 0;
180 }
树的统计
原文地址:https://www.cnblogs.com/3200Pheathon/p/11402309.html