[ZJOI2008]树的统计Count

来源:互联网 发布:sql server 查询二进制 编辑:程序博客网 时间:2024/05/20 06:39
                                      [ZJOI2008]树的统计Count

 

【题目描述】

一棵树上有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”的形式给出。 对于100%的数据,保证1<=n<=30000,0<=q<=200000;中途操作中保证每个节点的权值w在-30000到30000之间。

【输出格式】

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

【样例输入】

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  

【样例输出】

4  1  2  2  10  6  5  6  5  16


树剖模板,注意细节

  1 #include <cstring>  2 #include <ctype.h>  3 #include <cstdio>  4   5 const int MAXN=60010;  6 const int INF=1e9;  7   8 int n,q,inr;  9  10 int a[MAXN],id[MAXN],son[MAXN],fa[MAXN]; 11 int rank[MAXN],siz[MAXN],dep[MAXN],top[MAXN]; 12  13 struct SegmentTree { 14     int l,r; 15     int mx,sum; 16 }; 17 SegmentTree t[MAXN<<2]; 18  19 struct SKT { 20     int to; 21     int next; 22 }; 23 SKT e[MAXN<<2]; 24  25 int head[MAXN],tot; 26  27 inline void read(int&x) { 28     int f=1;register char c=getchar(); 29     for(x=0;!isdigit(c);c=='-'&&(f=-1),c=getchar()); 30     for(;isdigit(c);x=x*10+c-48,c=getchar()); 31     x=x*f; 32 } 33  34 inline void add(int x,int y) { 35     e[++tot].to=y; 36     e[tot].next=head[x]; 37     head[x]=tot; 38 } 39  40 void Dfs_1(int now,int f) { 41     dep[now]=dep[f]+1; 42     siz[now]=1; 43     fa[now]=f; 44     for(int i=head[now];i;i=e[i].next) { 45         int to=e[i].to; 46         if(to==f) continue; 47         Dfs_1(to,now); 48         siz[now]+=siz[to]; 49         if(son[now]==-1||siz[son[now]]<siz[to]) son[now]=to; 50     } 51 } 52  53 void Dfs_2(int now,int tp) { 54     top[now]=tp; 55     id[now]=++inr; 56     rank[id[now]]=now; 57     if(son[now]==-1) return; 58     Dfs_2(son[now],tp); 59     for(int i=head[now];i;i=e[i].next) { 60         int to=e[i].to; 61         if(to==fa[now]||to==son[now]) continue; 62         Dfs_2(to,to); 63     } 64 } 65  66 inline int max(int a,int b) { 67     return a<b?b:a; 68 } 69  70 inline void swap(int&x,int&y) { 71     int t=x;x=y;y=t; 72 } 73  74 inline void up(int now) { 75     t[now].sum=t[now<<1].sum+t[now<<1|1].sum; 76     t[now].mx=max(t[now<<1].mx,t[now<<1|1].mx); 77     return; 78 } 79  80 void build_tree(int now,int l,int r) { 81     t[now].l=l;t[now].r=r; 82     if(l==r) { 83         t[now].mx=t[now].sum=a[rank[l]]; 84         return; 85     } 86     int mid=(l+r)>>1; 87     build_tree(now<<1,l,mid); 88     build_tree(now<<1|1,mid+1,r); 89     up(now); 90 } 91  92 void modify(int now,int pos,int val) { 93     if(t[now].l==t[now].r) { 94         t[now].sum=val; 95         t[now].mx=val; 96         return; 97     } 98     t[now].mx=-INF; 99     int mid=(t[now].l+t[now].r)>>1;100     if(pos<=mid) modify(now<<1,pos,val);101     else modify(now<<1|1,pos,val);102     up(now);103 }104 105 int query_max(int now,int l,int r) {106     int ans=-INF;107     if(l<=t[now].l&&r>=t[now].r) return t[now].mx;108     int mid=(t[now].l+t[now].r)>>1;109     if(l<=mid) ans=max(ans,query_max(now<<1,l,r));110     if(r>mid) ans=max(ans,query_max(now<<1|1,l,r));111     return ans;112 }113 114 int query_sum(int now,int l,int r) {115     int ans=0;116     if(l<=t[now].l&&r>=t[now].r) return t[now].sum;117     int mid=(t[now].l+t[now].r)>>1;118     if(l<=mid) ans+=query_sum(now<<1,l,r);119     if(r>mid) ans+=query_sum(now<<1|1,l,r);120     return ans;121 }122 123 inline void Pre_query(int x,int y,char c) {124     int ans_mx=-INF,ans_sum=0;125     while(top[x]!=top[y]) {126         if(dep[top[x]]<dep[top[y]]) swap(x,y);127         if(c=='X') ans_mx=max(ans_mx,query_max(1,id[top[x]],id[x]));128         else ans_sum+=query_sum(1,id[top[x]],id[x]);129         x=fa[top[x]];130     }131     if(dep[x]>dep[y]) swap(x,y);132     if(c=='X') ans_mx=max(ans_mx,query_max(1,id[x],id[y])),printf("%d\n",ans_mx);133     else ans_sum+=query_sum(1,id[x],id[y]),printf("%d\n",ans_sum);134     return;135 }136 137 int hh() {138     freopen("bzoj_1036.in","r",stdin);139     freopen("bzoj_1036.out","w",stdout);140     read(n);141     int x,y,z;142     char opt[10];143     for(int i=1;i<n;++i) {144         read(x);read(y);145         add(x,y);add(y,x);146     }147     memset(son,-1,sizeof son);148     for(int i=1;i<=n;++i) read(a[i]);149     Dfs_1(1,0);Dfs_2(1,1);150     build_tree(1,1,inr);151     read(q);152     while(q--) {153         scanf("%s",opt);read(x);read(y);154         if(opt[0]!='Q') modify(1,id[x],y);155         else Pre_query(x,y,opt[3]);156     }157     return 0;158 }159 160 int sb=hh();161 int main() {;}
代码


原创粉丝点击