bzoj1036:[Zjoi2008]树的统计

Description

 

 

一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w。 
我们将以下面的形式来要求你对这棵树完成一些操作: 
I. CHANGE u t : 把结点u的权值改为t 
II. QMAX u v: 询问从点u到点v的路径上的节点的最大权值 
III. QSUM u v: 询问从点u到点v的路径上的节点的权值和 
注意:从点u到点v的路径上的节点包括u和v本身 

Input

输入文件的第一行为一个整数n,表示节点的个数。 
接下来n – 1行,每行2个整数a和b,表示节点a和节点b之间有一条边相连。 
接下来n行,每行一个整数,第i行的整数wi表示节点i的权值。 
接下来1行,为一个整数q,表示操作的总数。 
接下来q行,每行一个操作,以“CHANGE u t”或者“QMAX u v”或者“QSUM u v”的形式给出。 
保证1<=n<=30000,0<=q<=200000;中途操作中保证每个节点的权值w在-30000到30000之间。 

Output

对于每个“QMAX”或者“QSUM”的操作,每行输出一个整数表示要求输出的结果。

Sample Input

4
1 2
2 3
4 1
4 2 1 3
12
QMAX 3 4
QMAX 3 3
QMAX 3 2
QMAX 2 3
QSUM 3 4
QSUM 2 1
CHANGE 1 5
QMAX 3 4
CHANGE 3 6
QMAX 3 4
QMAX 2 4
QSUM 3 4

Sample Output

4
1
2
2
10
6
5
6
5
16

现在很晚了,这种板子题我也不知道怎么表述。

 

到时候再补吧,先丢代码

  1 #include<cstdio>
  2 #include<algorithm>
  3 using namespace std;
  4 const int N=60001;
  5 int n,m,cnt,now,son[N],f[N],nex[N],h[N],top[N],id[N],size[N],dep[N],ans,mxx;
  6 struct oo{int a,b,v,sum,mx;}s[N*2-20000];
  7 void ins(int x,int y)
  8 {
  9     son[++cnt]=y;
 10     nex[cnt]=h[x];
 11     h[x]=cnt;
 12 }
 13 void dfs(int x)
 14 {
 15     size[x]=1;
 16     for(int i=h[x];i;i=nex[i])
 17     {
 18         int v=son[i];
 19         if(v==f[x])continue;
 20         dep[v]=dep[x]+1;
 21         f[v]=x;
 22         dfs(v);
 23         size[x]+=size[v];
 24     }
 25 }
 26 void dfs2(int x,int y)
 27 {
 28     int k=0;
 29     id[x]=++now;top[x]=y;
 30     for(int i=h[x];i;i=nex[i])
 31         if(dep[son[i]]>dep[x]&&size[son[i]]>size[k])
 32             k=son[i];
 33     if(k==0)return ;
 34     dfs2(k,y);
 35     for(int i=h[x];i;i=nex[i])
 36     {
 37         if(son[i]==k)continue;
 38         if(dep[son[i]]>dep[x])
 39             dfs2(son[i],son[i]);
 40     }
 41 }
 42 void build(int x,int l,int r)
 43 {
 44     s[x].a=l,s[x].b=r;
 45     if(l==r){s[x].mx=-9999999;return ;}
 46     build(x<<1,l,l+r>>1);
 47     build(x<<1|1,(l+r>>1)+1,r);
 48 }
 49 void change(int x,int l,int v)
 50 {
 51     if(s[x].a==s[x].b){s[x].v=v;s[x].sum=v;s[x].mx=v;return ;}
 52     int mid=s[x].a+s[x].b>>1;
 53     if(l<=mid)change(x<<1,l,v);
 54     else change(x<<1|1,l,v);
 55     s[x].mx=max(s[x<<1].mx,s[x<<1|1].mx);
 56     s[x].sum=s[x<<1].sum+s[x<<1|1].sum;
 57 }
 58 void get(int x,int l,int r)
 59 {
 60     if(l<=s[x].a&&r>=s[x].b)
 61         ans+=s[x].sum,mxx=max(mxx,s[x].mx);
 62     else
 63     {
 64         int mid=s[x].a+s[x].b>>1;
 65         if(l<=mid)get(x<<1,l,r);
 66         if(r>mid)get(x<<1|1,l,r);
 67     }
 68 }
 69 void qmax(int x,int y)
 70 {
 71     int mx=-99999999;
 72     while(top[x]!=top[y])
 73     {
 74         if(dep[top[x]]<dep[top[y]])swap(x,y);
 75         mxx=-99999999;ans=0;
 76         get(1,id[top[x]],id[x]);
 77         mx=max(mx,mxx);
 78         x=f[top[x]];
 79     }
 80     if(id[x]>id[y])swap(x,y);
 81     mxx=-99999999;ans=0;
 82     get(1,id[x],id[y]);
 83     mx=max(mx,mxx);
 84     printf("%d\n",mx);
 85 }
 86 void qsum(int x,int y)
 87 {
 88     int sum=0;
 89     while(top[x]!=top[y])
 90     {
 91         if(dep[top[x]]<dep[top[y]])swap(x,y);
 92         ans=0;
 93         get(1,id[top[x]],id[x]);
 94         sum+=ans;
 95         x=f[top[x]];
 96     }
 97     if(id[x]>id[y])swap(x,y);
 98     ans=0;
 99     get(1,id[x],id[y]);
100     sum+=ans;
101     printf("%d\n",sum);
102 }
103 int main()
104 {
105     scanf("%d",&n);
106     for(int i=1,x,y;i<n;i++)
107         scanf("%d%d",&x,&y),ins(x,y),ins(y,x);
108     dfs(1),dfs2(1,1);build(1,1,n);
109     for(int i=1,x;i<=n;i++)
110         scanf("%d",&x),change(1,id[i],x);
111     scanf("%d",&m);char p[13];int a,b;
112     while(m--)
113     {
114         scanf("%s",p+1);
115         if(p[2]=='S')
116         {
117             scanf("%d%d",&a,&b);
118             qsum(a,b);
119         }
120         if(p[2]=='M')
121         {
122             scanf("%d%d",&a,&b);
123             qmax(a,b);
124         }
125         if(p[2]=='H')
126         {
127             scanf("%d%d",&a,&b);
128             change(1,id[a],b);
129         }
130     }
131 }

 

posted @ 2018-08-08 11:09  蒟蒻--lichenxi  阅读(153)  评论(0编辑  收藏  举报