• 【BZOJ1036】 树的统计Count (树链剖分)


    Description

      一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w。我们将以下面的形式来要求你对这棵树完成
    一些操作: I. CHANGE u t : 把结点u的权值改为t II. QMAX u v: 询问从点u到点v的路径上的节点的最大权值 I
    II. 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”的操作,每行输出一个整数表示要求输出的结果。

    Sample Input

    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

    Sample Output

    4
    1
    2
    2
    10
    6
    5
    6
    5
    16
     
     
    【题意】

      给出一棵树,每个点有一个权值,要求三种操作:1.修改某个点的权值,2.询问x到y路径上各点的权值最大值,3.询问x到y路径上各点的权值之和。

    【分析】

      树链剖分+线段树维护。这题维护的是点的值。

    代码如下:

      1 #include<cstdio>
      2 #include<cstdlib>
      3 #include<cstring>
      4 #include<iostream>
      5 #include<algorithm>
      6 using namespace std;
      7 #define Maxn 30010
      8 #define INF 0xfffffff
      9 
     10 struct node
     11 {
     12     int x,y,next;
     13 }t[2*Maxn];int len=0;
     14 
     15 int first[Maxn],fa[Maxn],dep[Maxn],top[Maxn],w[Maxn],size[Maxn],son[Maxn];
     16 int wl=0;
     17 
     18 struct nnode
     19 {
     20     int l,r,lc,rc,mx,sum;
     21 }tr[2*Maxn];int tl=0;
     22 
     23 int mymax(int x,int y) {return x>y?x:y;}
     24 
     25 void ins(int x,int y)
     26 {
     27     t[++len].x=x;t[len].y=y;
     28     t[len].next=first[x];first[x]=len;
     29 }
     30 
     31 void dfs1(int x,int f)
     32 {
     33     dep[x]=dep[f]+1;
     34     size[x]=1;fa[x]=f;son[x]=0;
     35     for(int i=first[x];i;i=t[i].next) if(t[i].y!=f)
     36     {
     37         dfs1(t[i].y,x);
     38         size[x]+=size[t[i].y];
     39         if(size[t[i].y]>size[son[x]]) son[x]=t[i].y;
     40     }
     41 }
     42 
     43 void dfs2(int x,int tp)
     44 {
     45     top[x]=tp;w[x]=++wl;
     46     if(size[x]!=1) dfs2(son[x],tp);
     47     for(int i=first[x];i;i=t[i].next) if(t[i].y!=fa[x]&&t[i].y!=son[x])
     48     {
     49         dfs2(t[i].y,t[i].y);
     50     }
     51 }
     52 
     53 int build(int l,int r)
     54 {
     55     int x=++tl;
     56     tr[x].l=l;tr[x].r=r;tr[x].mx=-INF;tr[x].sum=0;
     57     if(l!=r)
     58     {
     59         int mid=(l+r)>>1;
     60         tr[x].lc=build(l,mid);
     61         tr[x].rc=build(mid+1,r);
     62     }
     63     return x;
     64 }
     65 
     66 void change(int x,int y,int z)
     67 {
     68     if(tr[x].l==tr[x].r)
     69     {
     70         tr[x].mx=tr[x].sum=z;
     71         return;
     72     }
     73     int mid=(tr[x].l+tr[x].r)>>1;
     74     if(y<=mid) change(tr[x].lc,y,z);
     75     else change(tr[x].rc,y,z);
     76     tr[x].mx=mymax(tr[tr[x].lc].mx,tr[tr[x].rc].mx);
     77     tr[x].sum=tr[tr[x].lc].sum+tr[tr[x].rc].sum;
     78 }
     79 
     80 int queryt(int x,int l,int r,bool p)
     81 {
     82     if(tr[x].l==l&&tr[x].r==r)
     83     {
     84         if(p) return tr[x].mx;
     85         return tr[x].sum;
     86     }
     87     int mid=(tr[x].l+tr[x].r)>>1;
     88     if(r<=mid) return queryt(tr[x].lc,l,r,p);
     89     else if(l>mid) return queryt(tr[x].rc,l,r,p);
     90     if(p) return mymax(queryt(tr[x].lc,l,mid,p),queryt(tr[x].rc,mid+1,r,p));
     91     return queryt(tr[x].lc,l,mid,p)+queryt(tr[x].rc,mid+1,r,p);
     92 }
     93 
     94 int query(int x,int y,bool p)
     95 {
     96     int f1=top[x],f2=top[y];
     97     int ans=0;
     98     if(p) ans=-INF;
     99     while(f1!=f2)
    100     {
    101         if(dep[f1]<dep[f2])
    102         {
    103             swap(f1,f2);
    104             swap(x,y);
    105         }
    106         if(p) ans=mymax(ans,queryt(1,w[f1],w[x],p));
    107         else ans+=queryt(1,w[f1],w[x],p);
    108         x=fa[f1];
    109         f1=top[x];
    110     }
    111     if(dep[x]<dep[y]) swap(x,y);
    112     if(p) ans=mymax(ans,queryt(1,w[y],w[x],p));
    113     else ans+=queryt(1,w[y],w[x],p);
    114     return ans;
    115 }
    116 
    117 int main()
    118 {
    119     int n;
    120     scanf("%d",&n);
    121     memset(first,0,sizeof(first));
    122     for(int i=1;i<n;i++)
    123     {
    124         int x,y;
    125         scanf("%d%d",&x,&y);
    126         ins(x,y);ins(y,x);
    127     }
    128     dep[0]=0;size[0]=0;
    129     dfs1(1,0);
    130     dfs2(1,1);
    131     build(1,n);
    132     for(int i=1;i<=n;i++)
    133     {
    134         int x;
    135         scanf("%d",&x);
    136         change(1,w[i],x);
    137     }
    138     int m;
    139     char s[10];
    140     scanf("%d",&m);
    141     while(m--)
    142     {
    143         int x,y;
    144         scanf("%s%d%d",s,&x,&y);
    145         if(s[0]=='C')
    146         {
    147             change(1,w[x],y);
    148         }
    149         else if(s[1]=='S')
    150         {
    151             printf("%d
    ",query(x,y,0));
    152         }
    153         else
    154         {
    155             printf("%d
    ",query(x,y,1));
    156         }
    157     }
    158     return 0;
    159 }
    [BZOJ1036]

    2016-05-10 16:54:19

  • 相关阅读:
    Reverse Bits
    Number of 1 Bits
    Single Number,Single Number II
    Repeated DNA Sequences
    Fraction to Recurring Decimal
    Isomorphic Strings
    Valid Sudoku
    Count Primes
    Bulls and Cows
    高性能Web服务器Nginx的配置与部署研究(12)应用模块之Memcached做文件缓存时压缩引起的问题
  • 原文地址:https://www.cnblogs.com/Konjakmoyu/p/5478406.html
Copyright © 2020-2023  润新知