zoukankan      html  css  js  c++  java
  • bzoj1036 [ZJOI2008]树的统计Count (树链剖分+线段树)

    1036: [ZJOI2008]树的统计Count

    Time Limit: 10 Sec  Memory Limit: 162 MB
    Submit: 17941  Solved: 7305
    [Submit][Status][Discuss]

    Description

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

    Input

      输入的第一行为一个整数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之间。

    Output

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

     

     

    树剖模板dearu;

     

    ↓代码

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<string>
      5 #include<cmath>
      6 #include<algorithm>
      7 #include<vector>
      8 #include<complex>
      9 #define N 50039
     10 #define inf 0x7fffffff 
     11 #define ll long long
     12 using namespace std;
     13 struct segtree
     14 {
     15     int l,r,m,w,lazy;
     16     bool clr()
     17     {
     18         lazy=w=0;
     19         m=-inf;
     20     }
     21 }tree[4*N];
     22 vector<int> map[N];
     23 int dep[N],siz[N],fa[N],son[N],top[N],id[N],tot=0;
     24 void get_size(int pos,int pre,int de)
     25 {
     26     dep[pos]=de,son[pos]=0,siz[pos]=1,fa[pos]=pre;
     27     int a,b;
     28     for(a=0;a<map[pos].size();a++)
     29     {
     30         b=map[pos][a];
     31         if(b!=pre)
     32         {
     33             get_size(b,pos,de+1);
     34             siz[pos]+=siz[b];
     35             if(siz[b]>siz[son[pos]])
     36             {
     37                 son[pos]=b;
     38             }
     39         }
     40     }
     41 }
     42 void get_id(int pos,int tp)
     43 {
     44     top[pos]=tp,id[pos]=++tot;
     45     if(son[pos]!=0)
     46     {
     47         get_id(son[pos],tp);
     48     }
     49     int a,b;
     50     for(a=0;a<map[pos].size();a++)
     51     {
     52         b=map[pos][a];
     53         if(b!=son[pos] && b!=fa[pos])
     54         {
     55             get_id(b,b);
     56         }
     57     }
     58 }
     59 void pull_up(int k)
     60 {
     61     tree[k].w=tree[2*k].w+tree[2*k+1].w;
     62     tree[k].m=max(tree[2*k].m,tree[2*k+1].m);
     63 }
     64 void build_tree(int k,int l,int r)
     65 {
     66     tree[k].l=l,tree[k].r=r;
     67     tree[k].clr();
     68     if(l==r)
     69     {
     70         return;
     71     }
     72     int mid=(l+r)>>1;
     73     build_tree(2*k,l,mid);
     74     build_tree(2*k+1,mid+1,r);
     75 }
     76 void update_single(int k,int pos,int val)
     77 {
     78     if(tree[k].l==pos && tree[k].r==pos)
     79     {
     80         tree[k].w=tree[k].m=val;
     81         return;
     82     }
     83     if(tree[k].r<pos || tree[k].l>pos)
     84     {
     85         return;
     86     }
     87     update_single(2*k,pos,val);
     88     update_single(2*k+1,pos,val);
     89     pull_up(k); 
     90 }
     91 int query_sum(int k,int l,int r)
     92 {
     93     if(tree[k].l>=l && tree[k].r<=r)
     94     {
     95         return tree[k].w;
     96     }
     97     if(tree[k].r<l || tree[k].l>r)
     98     {
     99         return 0;
    100     }
    101     return query_sum(2*k,l,r)+query_sum(2*k+1,l,r);
    102 }
    103 int query_max(int k,int l,int r)
    104 {
    105     if(tree[k].l>=l && tree[k].r<=r)
    106     {
    107         return tree[k].m;
    108     }
    109     if(tree[k].r<l || tree[k].l>r)
    110     {
    111         return -inf;
    112     }
    113     return max(query_max(2*k,l,r),query_max(2*k+1,l,r));
    114 } 
    115 int solve_sum(int i,int j)
    116 {
    117     int res=0;
    118     while(top[i]!=top[j])
    119     {
    120         if(dep[top[i]]<dep[top[j]])
    121         {
    122             swap(i,j);
    123         }
    124         res+=query_sum(1,id[top[i]],id[i]);
    125         i=fa[top[i]];
    126     }
    127     if(id[i]>id[j])
    128     {
    129         swap(i,j);
    130     }
    131     res+=query_sum(1,id[i],id[j]);
    132     return res;
    133 }
    134 int solve_max(int i,int j)
    135 {
    136     int res=-inf;
    137     while(top[i]!=top[j])
    138     {
    139         if(dep[top[i]]<dep[top[j]])
    140         {
    141             swap(i,j);
    142         }
    143         res=max(res,query_max(1,id[top[i]],id[i]));
    144         i=fa[top[i]];
    145     }
    146     if(id[i]>id[j])
    147     {
    148         swap(i,j);
    149     }
    150     res=max(res,query_max(1,id[i],id[j]));
    151     return res;
    152 }
    153 int main()
    154 {
    155     char ch[39];
    156     int n,m,a,b,c;
    157     scanf("%d",&n);
    158     for(a=1;a<n;a++)
    159     {
    160         scanf("%d%d",&b,&c);
    161         map[b].push_back(c);
    162         map[c].push_back(b);
    163     }
    164     siz[0]=-1;
    165     get_size(1,1,0);
    166     get_id(1,1);
    167     build_tree(1,1,n);
    168     for(a=1;a<=n;a++)
    169     {
    170         scanf("%d",&b);
    171         update_single(1,id[a],b);
    172     }
    173     scanf("%d",&m);
    174     while(m--)
    175     {
    176         scanf("%s",ch);
    177         scanf("%d%d",&a,&b);
    178         if(ch[0]=='C')
    179         {
    180             update_single(1,id[a],b); 
    181         }
    182         else
    183         {
    184             if(ch[1]=='S')
    185             {
    186                 printf("%d\n",solve_sum(a,b));
    187             }
    188             if(ch[1]=='M')
    189             {
    190                 printf("%d\n",solve_max(a,b)); 
    191             }
    192         }
    193     }
    194     return 0;
    195 }
    bzoj1036
    散りぬべき 時知りてこそ 世の中の 花も花なれ 人も人なれ
  • 相关阅读:
    为什么要用getBaseContext()方法代替this?(转)
    如何让EditText不能自动获取焦点(转)
    context和getApplicationContext()的区别
    Idea 破解
    mysql 免安装
    AngularJS
    GC垃圾回收机制
    JVM类加载机制
    线程池
    面试-数据库
  • 原文地址:https://www.cnblogs.com/Sinogi/p/7360843.html
Copyright © 2011-2022 走看看