ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

[ZJOI2008]树的统计

2019-07-25 12:55:33  阅读:216  来源: 互联网

标签:int top QMAX son seg ZJOI2008 节点 统计


题目描述

一棵树上有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本身

输入格式

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

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

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

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

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

输出格式

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

输入输出样例

输入 #1

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

输出 #1

4
1
2
2
10
6
5
6
5
16

说明/提示

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

 

分析:

一道比树剖模板题还简单的。。。模板题???emmmm。。。

 

CODE:

  1 #include<cmath>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<iostream>
  5 #include<algorithm>
  6 using namespace std;
  7 const int N=30005;
  8 const int M=100005;
  9 int n,m,summ,maxx;
 10 int seg[M],rev[M],size[M],son[M],top[M],dep[M];
 11 int sum[M],num[M],father[M],Max[M];
 12 int head[M],next[M],to[M],tot;
 13 inline int read(){
 14     int res=0;
 15     int f=1;
 16     char c=getchar();
 17     while (c>'9'||c<'0') {
 18         if (c=='-') f=-1;
 19         c=getchar();
 20     }
 21     while (c<='9'&&c>='0') {
 22         res=(res<<3)+(res<<1)+c-'0';
 23         c=getchar();
 24     }
 25     return res*f;
 26 }
 27 void add(int u,int v){
 28     next[++tot]=head[u];
 29     head[u]=tot;
 30     to[tot]=v;
 31     return ;
 32 }
 33 inline void insert(int u,int v){
 34     add(u,v);
 35     add(v,u);
 36     return ;
 37 }
 38 void query(int k,int l,int r,int L,int R){
 39     if (L>r||R<l) return ;
 40     if (L<=l&&r<=R) {
 41         summ+=sum[k];
 42         maxx=max(maxx,Max[k]);
 43         return ;
 44     }
 45     int m=l+r>>1;
 46     if (m>=L) query(k<<1,l,m,L,R);
 47     if (m<R) query(k<<1|1,m+1,r,L,R);
 48 }
 49 void change(int k,int l,int r,int val,int pos){
 50     if (pos>r||pos<l) return ;
 51     if (l==r&&r==pos){
 52         sum[k]=val;
 53         Max[k]=val;
 54         return ;
 55     }
 56     int m=l+r>>1;
 57     if (m>=pos) change(k<<1,l,m,val,pos);
 58     if (m<pos) change(k<<1|1,m+1,r,val,pos);
 59     sum[k]=sum[k<<1]+sum[k<<1|1];
 60     Max[k]=max(Max[k<<1],Max[k<<1|1]);
 61 }
 62 void build(int k,int l,int r){
 63     int m=l+r>>1;
 64     if (l==r){Max[k]=sum[k]=num[rev[l]];return;}
 65     build(k<<1,l,m);
 66     build(k<<1|1,m+1,r);
 67     sum[k]=sum[k<<1]+sum[k<<1|1];
 68     Max[k]=max(Max[k<<1],Max[k<<1|1]);
 69     return;
 70 }
 71 void dfs1(int u,int fa){
 72     dep[u]=dep[fa]+1;
 73     father[u]=fa;
 74     size[u]=1;
 75     for (int i=head[u];i;i=next[i]){
 76         int v=to[i];
 77         if (v!=fa){
 78             dfs1(v,u);
 79             size[u]+=size[v];
 80             if (size[v]>size[son[u]]) son[u]=v;
 81         }
 82     }
 83     return;
 84 }
 85 void dfs2(int u,int fa){
 86     if (son[u]){
 87         seg[son[u]]=++seg[0];
 88         top[son[u]]=top[u];
 89         rev[seg[0]]=son[u];
 90         dfs2(son[u],u);
 91     }
 92     for (int i=head[u];i;i=next[i]){
 93         int v=to[i];
 94         if (!top[v]) {
 95             seg[v]=++seg[0];
 96             rev[seg[0]]=v;
 97             top[v]=v;
 98             dfs2(v,u);
 99         }
100     }
101     return;
102 }
103 void ask(int x,int y){
104     int fx=top[x],fy=top[y];
105     while (fx!=fy){
106         if (dep[fx]<dep[fy]) swap(x,y),swap(fx,fy);
107         query(1,1,seg[0],seg[fx],seg[x]);
108         x=father[fx];fx=top[x];
109     }
110     if (dep[x]>dep[y]) swap(x,y);
111     query(1,1,seg[0],seg[x],seg[y]);
112 }
113 int main() {
114     n=read();
115     for (int i=1;i<n;i++) insert(read(),read());
116     for (int i=1;i<=n;i++) num[i]=read();
117     dfs1(1,0);
118     seg[0]=seg[1]=top[1]=rev[1]=1;
119     dfs2(1,0);
120     build(1,1,seg[0]);
121     m=read();
122     while (m--){
123         char s[15];
124         int u,v;
125         cin>>s+1;
126         u=read(),v=read();
127         if (s[1]=='C') change(1,1,seg[0],v,seg[u]);
128         else{
129             summ=0;
130             maxx=-1<<30;
131             ask(u,v);
132             if (s[2]=='M') cout<<maxx<<endl;
133             else cout<<summ<<endl;
134         }
135     }
136     //system("pause");
137     return 0;
138 }

 

标签:int,top,QMAX,son,seg,ZJOI2008,节点,统计
来源: https://www.cnblogs.com/kanchuang/p/11243538.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有