zoukankan      html  css  js  c++  java
  • Codevs 2460 == BZOJ 1036 树的统计

            2460 树的统计

            2008年省队选拔赛浙江

    时间限制: 2 s    空间限制: 128000 KB    题目等级 : 大师 Master
    题目描述 Description

    一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w。

    我们将以下面的形式来要求你对这棵树完成一些操作:

    1. I.                    CHANGE u t : 把结点u的权值改为t
    2. II.                 QMAX u v: 询问从点u到点v的路径上的节点的最大权值
    3. III.               QSUM u v: 询问从点u到点v的路径上的节点的权值和

     

    注意:从点u到点v的路径上的节点包括u和v本身

    输入描述 Input Description

    输入文件的第一行为一个整数n,表示节点的个数。

           接下来n – 1行,每行2个整数a和b,表示节点a和节点b之间有一条边相连。

           接下来n行,每行一个整数,第i行的整数wi表示节点i的权值。

           接下来1行,为一个整数q,表示操作的总数。

    接下来q行,每行一个操作,以“CHANGE u t”或者“QMAX u v”或者“QSUM u v”的形式给出。

     

    输出描述 Output Description

           对于每个“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

    数据范围及提示 Data Size & Hint

    对于100%的数据,保证1<=n<=30000,0<=q<=200000;中途操作中保证每个节点的权值w在-30000到30000之间。

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #define maxn 300001
      5 using namespace std;
      6 int head[maxn],dep[maxn],fa[maxn],a[maxn];
      7 int pos[maxn],top[maxn],size[maxn],son[maxn];
      8 int tot,n,m,cnt,maxsize,x,y,num;
      9 struct Edge{int next,to;}e[maxn<<1];
     10 struct Node{int l,r,max,sum;}tre[maxn<<2];
     11 int read(){
     12     int x=0,f=1;char c=getchar();
     13     while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
     14     while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
     15     return x*f;
     16 }
     17 int max(int a,int b){if(a>b)return a;else return b;}
     18 void Add_Edge(int u,int v){
     19     e[++num].to=v;e[num].next=head[u];head[u]=num;
     20 }
     21 void DFS_First(int now,int pre,int deepth){
     22     dep[now] = deepth; fa[now] = pre; size[now] = 1;
     23     for(int i=head[now];i;i=e[i].next){
     24         int v=e[i].to;
     25         if(v!=pre){
     26             DFS_First(v,now,deepth+1);
     27             size[now] += size[v];
     28             if(son[now]==-1||size[v]>size[son[now]])
     29                 son[now]=v;
     30         }
     31     }
     32 }
     33 void Get_Pos(int u,int Top){
     34     int k=0;maxsize++;
     35     pos[u]=maxsize;top[u]=Top;
     36     if(!son[u])return;
     37     Get_Pos(son[u],Top);
     38     for(int i=head[u];i;i=e[i].next)
     39         if(dep[e[i].to]>dep[u]&&e[i].to!=son[u])
     40             Get_Pos(e[i].to,e[i].to);
     41     return;
     42 }
     43 void Build(int now,int l,int r){
     44     tre[now].l=l;tre[now].r=r;
     45     if(l==r){
     46         tre[now].sum=tre[now].max=0;return ;
     47     }
     48     int mid=(l+r)>>1;
     49     Build(now<<1,l,mid);Build(now<<1|1,mid+1,r);
     50     tre[now].sum=tre[now<<1].sum+tre[now<<1|1].sum;
     51     tre[now].max=max(tre[now<<1].max,tre[now<<1|1].max);
     52     
     53 }
     54 void Insert(int now,int poss,int val){
     55     if(tre[now].l==tre[now].r){
     56         tre[now].sum=tre[now].max=val;return;
     57     }
     58     int mid=(tre[now].l+tre[now].r)/2;
     59     if(poss<=mid)Insert(now<<1,poss,val);
     60     else if(poss>mid)Insert(now<<1|1,poss,val);
     61     tre[now].sum=tre[now<<1].sum+tre[now<<1|1].sum;
     62     tre[now].max=max(tre[now<<1].max,tre[now<<1|1].max);
     63 }
     64 int QueryMax(int now,int l,int r){
     65     if(l<=tre[now].l&&tre[now].r<=r)return tre[now].max;
     66     int mid=(tre[now].l+tre[now].r)>>1,total=-1e9;
     67     if(l<=mid)total=max(total,QueryMax(now<<1,l,r));
     68     if(r>mid)total=max(total,QueryMax(now<<1|1,l,r));
     69     return total;
     70 }
     71 int QuerySum(int now,int l,int r){
     72     if(l<=tre[now].l&&tre[now].r<=r)return tre[now].sum;
     73     int mid=(tre[now].l+tre[now].r)>>1,total=0;
     74     if(l<=mid)total+=QuerySum(now<<1,l,r);
     75     if(r>mid)total+=QuerySum(now<<1|1,l,r);
     76     return total;
     77 }
     78 int SolveMax(int u,int v){
     79     int ans=-1e9;
     80     while(top[u]!=top[v]){
     81         if(dep[top[u]]<dep[top[v]])swap(u,v);
     82         ans=max(ans,QueryMax(1,pos[top[u]],pos[u]));
     83         u=fa[top[u]];
     84     }
     85     if(pos[u]>pos[v]) swap(u,v);
     86     ans=max(ans,QueryMax(1,pos[u],pos[v]));
     87     return ans;
     88 }
     89 int SolveSum(int u,int v){
     90     int ans=0;
     91     while(top[u]!=top[v]){
     92         if(dep[top[u]]<dep[top[v]])swap(u,v);
     93         ans+=QuerySum(1,pos[top[u]],pos[u]);
     94         u=fa[top[u]];
     95     }
     96     if(pos[u]>pos[v])swap(u,v);
     97     ans+=QuerySum(1,pos[u],pos[v]);
     98     return ans;
     99 }
    100 int main(){
    101     n=read();
    102     for(int i=1;i<n;i++){
    103         x=read();y=read();
    104         Add_Edge(x,y);Add_Edge(y,x);
    105     }
    106     for(int i=1;i<=n;i++) a[i]=read();
    107     DFS_First(1,0,0);
    108     Get_Pos(1,1);
    109     Build(1,1,maxsize);
    110     for(int i=1;i<=n;i++)
    111     Insert(1,pos[i],a[i]);
    112     m=read();char sp[25];
    113     while(m--){
    114         scanf("%s",sp);scanf("%d%d",&x,&y);
    115         if(sp[0]=='C')a[x]=y,Insert(1,pos[x],y);
    116         else{
    117             if(sp[1]=='M') printf("%d
    ",SolveMax(x,y));
    118             else printf("%d
    ",SolveSum(x,y));
    119         }
    120     }
    121     return 0;
    122 }
  • 相关阅读:
    洛谷 P2756 飞行员配对方案问题 (二分图匹配)
    HDU 1879 继续畅通工程 (最小生成树)
    POJ 3090 Visible Lattice Points (欧拉函数)
    SPOJ VFMUL
    洛谷 P3803 【模板】多项式乘法(FFT)
    JAVA MyBatis 逆向工程 遇到的坑
    RabbitMQ遇到的坑
    .net webapi action拦截器 统计action耗时
    CEFCharp下载问题
    【进击.NET高级程序员之路】【二】
  • 原文地址:https://www.cnblogs.com/suishiguang/p/6502339.html
Copyright © 2011-2022 走看看