zoukankan      html  css  js  c++  java
  • [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 }
  • 相关阅读:
    Jmeter 将正则表达式提取的参数传给全局(跨线程组使用变量)
    pod的状态分析
    前端 -- html介绍和head标签
    Python ----- 线程和进程
    网络编程 ------ 基础
    面向对象相关操作
    面向对象 --- 进阶篇
    python --- 面向对象
    python的模块和包的详细说明
    常用模块------时间模块 , random模块 ,os模块 , sys模块
  • 原文地址:https://www.cnblogs.com/kanchuang/p/11243538.html
Copyright © 2011-2022 走看看