• bzoj 1036 [ZJOI2008]树的统计Count 树链剖分模板


    1036: [ZJOI2008]树的统计Count

    Time Limit: 10 Sec  Memory Limit: 162 MB
    Submit: 18615  Solved: 7598
    [Submit][Status][Discuss]

    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
    -------------------------------------------------------------------------------------------------
    树链剖分模板题
    看黄学长的博客才会的
    个人理解:当你想要维护一棵每个点都有权值的树,让这棵树支持在线修改点权值、求点到点的路径上点权和or最大/小值时,就用树链剖分。
    剖分的方法有多种,这里用的轻重链。
    其原理就是:先找出这棵树的重链,然后按照轻重链给结点重新编号(一条重链上的点的新编号是连续的),然后再按照新编号将树上的所有结点压入数据结构,这里压入一棵线段树。
     后面就的操作就在线段树上进行,将路径尽量往重链上靠。
     
     
      1 #include<stdio.h>
      2 #include<string.h>
      3 #include<stdlib.h>
      4 #include<iostream>
      5 #define maxn 233333
      6 #define lson ro<<1
      7 #define rson ro<<1|1
      8 #define inf 1e9
      9 using namespace std;
     10 struct node{int to,next;};
     11 struct rode{int l,r,sum,mx;};
     12 node e[maxn];
     13 rode tr[maxn];
     14 int n,v[30010],pos[30010],dep[30010],pre[maxn],cnt,fa[30010],size[30010],sz,bl[30010],mxx,an,m;
     15 int read();
     16 void insert(int,int);
     17 void build(int,int,int);
     18 void pushup(int);
     19 void dfs1(int);
     20 void dfs2(int,int);
     21 void querymx(int,int,int);
     22 void querysum(int,int,int);
     23 int solvemx(int,int);
     24 int solvesum(int,int);
     25 void change(int,int,int);
     26 int main(){
     27     n=read();
     28     for(int i=1;i<n;i++)insert(read(),read());
     29     for(int i=1;i<=n;i++)v[i]=read();
     30     dfs1(1);
     31     dfs2(1,1);
     32     build(1,n,1);
     33     for(int i=1;i<=n;i++) change(pos[i],v[i],1);
     34     m=read();
     35     for(int i=1;i<=m;i++){
     36         char cuan[12];
     37         scanf(" %s",cuan);
     38         if(cuan[1]=='H'){
     39             int x=read(),k=read();
     40             change(pos[x],k,1);
     41         }
     42         else if(cuan[1]=='M') printf("%d
    ",solvemx(read(),read()));
     43         else printf("%d
    ",solvesum(read(),read()));
     44     }
     45     return 0;
     46 }
     47 int read(){
     48     int ans=0,f=1;char c=getchar();
     49     while('0'>c||c>'9'){if(c=='-')f=-1;c=getchar();}
     50     while('0'<=c&&c<='9')ans=ans*10+c-48,c=getchar();return ans*f;
     51 }
     52 void insert(int x,int y){
     53     e[++cnt].to=y;e[cnt].next=pre[x];pre[x]=cnt;
     54     e[++cnt].to=x;e[cnt].next=pre[y];pre[y]=cnt;
     55 }
     56 void build(int l,int r,int ro){
     57     tr[ro].l=l;tr[ro].r=r;
     58     if(l==r) return;
     59     int mid=(l+r)>>1;
     60     build(l,mid,lson);build(mid+1,r,rson);
     61 }
     62 void pushup(int ro){
     63     tr[ro].sum=tr[lson].sum+tr[rson].sum;
     64     tr[ro].mx=max(tr[lson].mx,tr[rson].mx);
     65 }
     66 void dfs1(int x){
     67     size[x]=1;
     68     for(int i=pre[x];i;i=e[i].next){
     69         int to=e[i].to;
     70         if(fa[x]==to)continue;
     71         fa[to]=x;
     72         dep[to]=dep[x]+1;
     73         dfs1(to);
     74         size[x]+=size[to];
     75     }
     76 }
     77 void dfs2(int x,int chain){
     78     int k=0;
     79     pos[x]=++sz;
     80     bl[x]=chain;
     81     for(int i=pre[x];i;i=e[i].next)
     82        if(dep[e[i].to]>dep[x]&&size[k]<size[e[i].to])
     83           k=e[i].to;
     84     if(k==0)return;
     85     dfs2(k,chain);
     86     for(int i=pre[x];i;i=e[i].next)
     87        if(dep[e[i].to]>dep[x]&&k!=e[i].to)
     88           dfs2(e[i].to,e[i].to);
     89 }
     90 void change(int x,int k,int ro){
     91     if(tr[ro].r==tr[ro].l){
     92         tr[ro].sum=tr[ro].mx=k;
     93         return;
     94     }
     95     int mid=(tr[ro].r+tr[ro].l)>>1;
     96     if(x<=mid) change(x,k,lson);
     97     else change(x,k,rson);
     98     pushup(ro);
     99 }
    100 void querymx(int l,int r,int ro){
    101     if(l<=tr[ro].l&&tr[ro].r<=r){
    102         mxx=max(mxx,tr[ro].mx);
    103         return;
    104     }
    105     int mid=(tr[ro].l+tr[ro].r)>>1;
    106     if(l<=mid) querymx(l,r,lson);
    107     if(r>mid)  querymx(l,r,rson);
    108 }
    109 void querysum(int l,int r,int ro){
    110     if(l<=tr[ro].l&&tr[ro].r<=r){
    111         an+=tr[ro].sum;
    112         return;
    113     }
    114     int mid=(tr[ro].l+tr[ro].r)>>1;
    115     if(l<=mid) querysum(l,r,lson);
    116     if(r>mid)  querysum(l,r,rson);
    117 }
    118 int solvemx(int x,int y){
    119     int mxs=-inf;
    120     while(bl[x]!=bl[y]){
    121         if(dep[bl[x]]<dep[bl[y]])swap(x,y);
    122         mxx=-inf;querymx(pos[bl[x]],pos[x],1);
    123         mxs=max(mxs,mxx);
    124         x=fa[bl[x]];
    125     }
    126     if(pos[x]>pos[y])swap(x,y);
    127     mxx=-inf;querymx(pos[x],pos[y],1);
    128     mxs=max(mxs,mxx);
    129     return mxs;
    130 }
    131 int solvesum(int x,int y){
    132     int sum=0;
    133     while(bl[x]!=bl[y]){
    134         if(dep[bl[x]]<dep[bl[y]])swap(x,y);
    135         an=0;querysum(pos[bl[x]],pos[x],1);
    136         sum+=an;
    137         x=fa[bl[x]];
    138     }
    139     if(pos[x]>pos[y])swap(x,y);
    140     an=0;querysum(pos[x],pos[y],1);
    141     sum+=an;
    142     return sum;
    143 }
    树链剖分
  • 相关阅读:
    不弹出提示直接关闭页面
    orcale表解锁
    序列化和反序列化
    js 实现post传参
    简易实现 instanceOf
    简易实现virtualdom
    react中setState同步、异步问题
    CMake Qt 配置 OpenCV
    VS执行时打开cmd
    VS2019+Qt5.15.2环境配置
  • 原文地址:https://www.cnblogs.com/lpl-bys/p/7571597.html
Copyright © 2020-2023  润新知