zoukankan      html  css  js  c++  java
  • 块状树 2460 树的统计 2008年省队选拔赛浙江

    /*

    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”的操作,每行输出一个整数表示要求输出的结果。*/


    #include<cstdio> #include<iostream> #include<cmath> using namespace std; int head[30008],next[60008],v[60008],n,w[30008],shu[30008],size[30008],fa[30008]; int deep[30008],len,head1[30008],next1[60008],v1[60008],cnt,maxx[30008],sum[30008]; void dfs(int a1) { for(int i=head[a1];i;i=next[i]) if(v[i]!=fa[a1]) { fa[v[i]]=a1; deep[v[i]]=deep[a1]+1; if(size[shu[a1]]<len) { size[shu[a1]]++; shu[v[i]]=shu[a1]; cnt++; next1[cnt]=head1[a1]; head1[a1]=cnt; v1[cnt]=v[i]; } dfs(v[i]); } return; } void dfs1(int a1,int a2,int a3) { a2+=w[a1]; sum[a1]=a2; a3=max(a3,w[a1]); maxx[a1]=a3; for(int i=head1[a1];i;i=next1[i]) dfs1(v1[i],a2,a3); return; } void gai(int a1,int a2) { w[a1]=a2; if(shu[a1]==a1) dfs1(a1,0,-1000000); else dfs1(a1,sum[fa[a1]],maxx[fa[a1]]); return; } pair<int,int> he(int a1,int a2) { int s=0,ma=-1000000; for(;a1!=a2;) { if(deep[a1]<deep[a2]) swap(a1,a2); if(shu[a1]==shu[a2]) { s+=w[a1]; ma=max(w[a1],ma); a1=fa[a1]; } else { if(deep[shu[a1]]<deep[shu[a2]]) swap(a1,a2); s+=sum[a1]; ma=max(maxx[a1],ma); a1=fa[shu[a1]]; } } s+=w[a1]; ma=max(w[a1],ma); return pair<int,int>(s,ma); } int main() { scanf("%d",&n); len=sqrt(n); for(int i=1;i<n;i++) { int a1,a2; scanf("%d%d",&a1,&a2); next[i]=head[a1]; head[a1]=i; v[i]=a2; next[i+n]=head[a2]; head[a2]=i+n; v[i+n]=a1; } for(int i=1;i<=n;i++) { scanf("%d",&w[i]); shu[i]=i; size[i]=1; } dfs(1); for(int i=1;i<=n;i++) if(shu[i]==i) dfs1(i,0,-100000); int m; scanf("%d",&m); for(int i=0;i<m;i++) { char ch[10]; int a1,a2; scanf("%s%d%d",ch,&a1,&a2); if(ch[0]=='C') gai(a1,a2); else { pair<int,int>anss=he(a1,a2); if(ch[1]=='S') printf("%d ",anss.first); else printf("%d ",anss.second); } } return 0; }
  • 相关阅读:
    如何修改mysql root密码
    【STL】list基础(转)
    时间控制timer settimeout setinterval
    刷新ArrayCollection的显示控件
    需要科普的网站
    flex 拖拽数据
    常用的资源网站
    as3 性能优化
    对象池
    Bitmap与Bitmapdata
  • 原文地址:https://www.cnblogs.com/xydddd/p/5149013.html
Copyright © 2011-2022 走看看