• 数据结构(LCT动态树):BZOJ 1036: [ZJOI2008]树的统计Count


    1036: [ZJOI2008]树的统计Count

    Time Limit: 10 Sec  Memory Limit: 162 MB
    Submit: 12266  Solved: 4945
    [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
      模板题,权当复习……
      1 #include <iostream>
      2 #include <cstring>
      3 #include <cstdio>
      4 using namespace std;
      5 const int maxn=30010;
      6 const int INF=1000000000;
      7 
      8 int n,Q;
      9 bool rt[maxn];
     10 long long sum[maxn];
     11 int ch[maxn][2],fa[maxn];
     12 int Mx[maxn],key[maxn],flip[maxn];
     13 int cnt,fir[maxn],nxt[maxn<<1],to[maxn<<1];
     14 
     15 void addedge(int a,int b){
     16     nxt[++cnt]=fir[a];fir[a]=cnt;to[cnt]=b;
     17 }
     18 
     19 void Push_up(int x){
     20     sum[x]=sum[ch[x][0]]+sum[ch[x][1]]+key[x];
     21     Mx[x]=max(max(Mx[ch[x][0]],Mx[ch[x][1]]),key[x]);
     22 }
     23 
     24 void Flip(int x){
     25     swap(ch[x][0],ch[x][1]);
     26     flip[x]^=1;
     27 }
     28 
     29 void Push_down(int x){
     30     if(flip[x]){
     31         Flip(ch[x][0]);
     32         Flip(ch[x][1]);
     33         flip[x]=0;
     34     }    
     35 }
     36 
     37 void Rotate(int x){
     38     int y=fa[x],g=fa[y],c=ch[y][1]==x;
     39     ch[y][c]=ch[x][c^1];fa[ch[y][c]]=y;
     40     ch[x][c^1]=y;fa[y]=x;fa[x]=g;
     41     if(rt[y])rt[y]=false,rt[x]=true;
     42     else ch[g][ch[g][1]==y]=x;
     43     Push_up(y);
     44 }
     45 
     46 void P(int x){
     47     if(!rt[x])P(fa[x]);
     48     Push_down(x);
     49 }
     50 
     51 void Splay(int x){
     52     P(x);
     53     for(int y=fa[x];!rt[x];Rotate(x),y=fa[x])
     54         if(!rt[y])Rotate((ch[fa[y]][1]==y)==(ch[y][1]==x)?y:x);
     55     Push_up(x);
     56 }
     57 
     58 void Access(int x){
     59     int y=0;
     60     while(x){
     61         Splay(x);
     62         rt[ch[x][1]]=true;
     63         rt[ch[x][1]=y]=false;
     64         Push_up(x);
     65         x=fa[y=x];
     66     }
     67 }
     68 
     69 void Lca(int &x,int &y){
     70     Access(y);y=0;
     71     while(true){
     72         Splay(x);
     73         if(!fa[x])return;
     74         rt[ch[x][1]]=true;
     75         rt[ch[x][1]=y]=false;
     76         Push_up(x);
     77         x=fa[y=x];
     78     }
     79 }    
     80 
     81 void Change(int x,int y){
     82     Splay(x);
     83     key[x]=y;
     84     Push_up(x);
     85 }
     86 
     87 void DFS(int x){
     88     for(int i=fir[x];i;i=nxt[i])
     89         if(fa[x]!=to[i]){
     90             fa[to[i]]=x;
     91             DFS(to[i]);
     92         }
     93 }
     94 
     95 char op[5];
     96 int main(){
     97     Mx[0]=-INF;
     98     scanf("%d",&n);
     99     for(int i=1,a,b;i<n;i++){
    100         scanf("%d%d",&a,&b);
    101         addedge(a,b);
    102         addedge(b,a);
    103     }
    104     for(int i=1;i<=n;i++){
    105         scanf("%d",&key[i]);
    106         rt[i]=true;
    107     }
    108     DFS(1);
    109     scanf("%d",&Q);
    110     int x,y;
    111     while(Q--){
    112         scanf("%s",op);
    113         if(op[0]=='C'){
    114             scanf("%d%d",&x,&y);
    115             Change(x,y);
    116         }
    117         else{
    118             scanf("%d%d",&x,&y);Lca(x,y);
    119             if(op[1]=='M')
    120                 printf("%d
    ",max(max(key[x],Mx[ch[x][1]]),Mx[y]));
    121             else
    122                 printf("%lld
    ",(long long)(key[x]+sum[ch[x][1]]+sum[y]));    
    123         }
    124     }
    125     return 0;
    126 }
    尽最大的努力,做最好的自己!
  • 相关阅读:
    Python的object和type理解及主要对象层次结构
    【译】Matplotlib:plotting
    random
    【译】itertools
    VBA笔记
    Python Function
    Outlook API
    VB参考
    类方法:绑定或无绑定
    【摘录】数据库连接参数
  • 原文地址:https://www.cnblogs.com/TenderRun/p/5580957.html
Copyright © 2020-2023  润新知