zoukankan      html  css  js  c++  java
  • luoguP2590 [ZJOI2008]树的统计 [树链剖分] [TLE的LCT]

    题目描述

    一棵树上有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之间。


    这题本身应该是一题树链剖分果题。。QAQ

      1 //不用lazy-tag真是爽! 
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<iostream>
      5 using namespace std;
      6 #define inf 0x3f3f3f3f
      7 #define ls x<<1
      8 #define rs x<<1|1
      9 
     10 int read(){
     11     char ch;
     12     int re=0;
     13     bool flag=0;
     14     while((ch=getchar())!='-'&&(ch<'0'||ch>'9'));
     15     ch=='-'?flag=1:re=ch-'0';
     16     while((ch=getchar())>='0'&&ch<='9')  re=re*10+ch-'0';
     17     return flag?-re:re;
     18 }
     19 
     20 struct Edge{
     21     int to,nxt;
     22     Edge(int to=0,int nxt=0):
     23         to(to),nxt(nxt){}
     24 };
     25 
     26 struct Segment{
     27     int l,r,su,mx;
     28     Segment(){
     29         mx=-inf;
     30     }
     31 };
     32 
     33 const int maxn=30005;
     34 
     35 int n,m,cnt=0,dc=1;
     36 int head[maxn],val[maxn];
     37 int top[maxn],dep[maxn],fa[maxn],id[maxn],son[maxn],sz[maxn];
     38 Edge G[maxn<<1];
     39 Segment T[maxn<<2];
     40 
     41 inline void a_ed(int from,int to){
     42     G[++cnt]=Edge(to,head[from]),head[from]=cnt;
     43     G[++cnt]=Edge(from,head[to]),head[to]=cnt;
     44 }
     45 
     46 inline void push_up(int x){
     47     T[x].mx=max(T[ls].mx,T[rs].mx);
     48     T[x].su=T[ls].su+T[rs].su;
     49 }
     50 
     51 void build(int x,int l,int r){
     52     T[x].l=l,T[x].r=r;
     53     if(l==r){
     54         T[x].su=T[x].mx=val[l];
     55         return;
     56     }
     57     int mid=l+r>>1;
     58     build(ls,l,mid);  build(rs,mid+1,r);
     59     push_up(x);
     60 }
     61 
     62 void update(int x,int M,int c){
     63     if(T[x].l==T[x].r){
     64         T[x].su=T[x].mx=c;
     65         return;
     66     }
     67     int mid=T[x].l+T[x].r>>1;
     68     if(M<=mid)  update(ls,M,c);
     69     else  update(rs,M,c);
     70     push_up(x);
     71 }
     72 
     73 int query(int x,int L,int R,bool kind){
     74     if(L<=T[x].l&&T[x].r<=R)
     75         if(kind)  return T[x].su;
     76         else  return T[x].mx;
     77     int mid=T[x].l+T[x].r>>1;
     78     if(R<=mid)  return query(ls,L,R,kind);
     79     else  if(L>mid)  return query(rs,L,R,kind);
     80     else{
     81         if(kind)  return query(ls,L,mid,kind)+query(rs,mid+1,R,kind);
     82         else  return max(query(ls,L,mid,kind),query(rs,mid+1,R,kind));
     83     }
     84 }
     85 
     86 void dfs1(int no,int p){
     87     fa[no]=p;
     88     sz[no]=1;
     89     dep[no]=dep[p]+1;
     90     for(int e=head[no];e;e=G[e].nxt){
     91         int nt=G[e].to;
     92         if(nt!=p){
     93             dfs1(nt,no);
     94             sz[no]+=sz[nt];
     95             if(!son[no]||sz[nt]>sz[son[no]])
     96                 son[no]=nt;
     97         }
     98     }
     99 }
    100 
    101 void dfs2(int no,int p){
    102     if(!son[no])  return;
    103     top[son[no]]=top[no];
    104     id[son[no]]=++dc;
    105     dfs2(son[no],no);
    106     for(int e=head[no];e;e=G[e].nxt){
    107         int nt=G[e].to;
    108         if(nt!=p&&nt!=son[no]){
    109             top[nt]=nt;
    110             id[nt]=++dc;
    111             dfs2(nt,no);
    112         }
    113     }
    114 }
    115 
    116 int calc(int x,int y,bool kind){
    117     int sum=0,f1=top[x],f2=top[y];
    118     if(!kind)  sum=-inf;
    119     while(f1!=f2){
    120         if(dep[f1]<dep[f2]){  swap(f1,f2),swap(x,y);  }
    121         if(kind)
    122             sum+=query(1,id[f1],id[x],kind);
    123         else
    124             sum=max(sum,query(1,id[f1],id[x],kind));
    125         x=fa[f1];
    126         f1=top[x];
    127     }
    128     if(dep[x]>dep[y])  swap(x,y);
    129     if(kind)  sum+=query(1,id[x],id[y],kind);
    130     else  sum=max(sum,query(1,id[x],id[y],kind));
    131     return sum;
    132 }
    133 
    134 int main(){
    135 //    freopen("temp.in","r",stdin);
    136     n=read();    
    137     for(int i=1,from,to;i<n;i++){
    138         from=read();  to=read();
    139         a_ed(from,to);
    140     }
    141     dfs1(1,0);
    142     top[1]=1;
    143     id[1]=1;
    144     dfs2(1,0);
    145     for(int i=1;i<=n;i++)  val[id[i]]=read();
    146     build(1,1,n);
    147     m=read();
    148     char opt[10];
    149     int x,y;
    150     while(m--){
    151         scanf("%s",opt);
    152         x=read(),y=read();
    153         switch(opt[1]){
    154             case 'H':{
    155                 update(1,id[x],y);
    156                 break;
    157             }
    158             case 'M':{
    159                 printf("%d
    ",calc(x,y,0));
    160                 break;
    161             }
    162             default:{
    163                 printf("%d
    ",calc(x,y,1));
    164                 break;
    165             }
    166         }
    167     }
    168     return 0;
    169 }

    刚学了LCT的我。。想用LCT过了这一题。。

    可是。。T了。。QAQ

    顺便终于明白、、把一堆变量包进一个结构体里还不用指针构成的splay还不如拆成一个个数组。。

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<iostream>
      4 using namespace std;
      5 #define rint register int
      6 #define inf 0x3f3f3f3f
      7 
      8 int read(){
      9     char ch;
     10     int re=0;
     11     bool flag=0;
     12     while((ch=getchar())!='-'&&(ch<'0'||ch>'9'));
     13     ch=='-'?flag=1:re=ch-'0';
     14     while((ch=getchar())>='0'&&ch<='9')  re=re*10+ch-'0';
     15     return flag?-re:re;
     16 }
     17 
     18 struct Edge{
     19     int to,nxt;
     20     Edge(int to=0,int nxt=0):
     21         to(to),nxt(nxt){}
     22 };
     23 
     24 const int maxn=30005;
     25 
     26 int n,m,cnt=0,top;
     27 //struct 变 数组 
     28 int ch[maxn][2],su[maxn],mx[maxn],fa[maxn],rev[maxn];
     29 int head[maxn],val[maxn],stk[maxn];
     30 Edge G[maxn<<1];
     31 
     32 inline void a_ed(int from,int to){
     33     G[++cnt]=Edge(to,head[from]);
     34     head[from]=cnt;
     35     G[++cnt]=Edge(from,head[to]);
     36     head[to]=cnt;
     37 }
     38 
     39 inline void push_up(int x){
     40     mx[x]=max(mx[ch[x][0]],max(mx[ch[x][1]],val[x]));
     41     su[x]=su[ch[x][0]]+su[ch[x][1]]+val[x];
     42 }
     43 
     44 inline void push_down(int x){
     45     if(rev[x]){
     46         rev[ch[x][0]]^=1,rev[ch[x][1]]^=1;
     47         swap(ch[x][0],ch[x][1]);
     48         rev[x]=0;
     49     }
     50 }
     51 
     52 inline bool isroot(int x){
     53     return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;
     54 }
     55 
     56 void rot(int x){
     57     int y=fa[x],z=fa[y],l,r;
     58     fa[x]=z;
     59     if(!isroot(y))  ch[z][ch[z][1]==y]=x;
     60     if(ch[y][0]==x)  l=0;
     61     else  l=1;
     62     r=l^1;
     63     fa[ch[x][r]]=y;
     64     ch[y][l]=ch[x][r];
     65     fa[y]=x;
     66     ch[x][r]=y;
     67     push_up(y),push_up(x);
     68 }
     69 
     70 void splay(int x){
     71     top=1;  stk[top]=x;
     72     for(rint i=x;!isroot(i);i=fa[i])  stk[++top]=fa[i];
     73     for(rint i=top;i;i--)  push_down(stk[i]);
     74     while(!isroot(x)){
     75         int y=fa[x],z=fa[y];
     76         if(!isroot(y)){
     77             if((ch[y][0]==x)^(ch[z][0]==y))  rot(x);
     78             else  rot(y);
     79         }
     80         rot(x);
     81     }
     82 }
     83 
     84 void acc(int x){
     85     int t=0;
     86     while(x){
     87         splay(x);
     88         ch[x][1]=t;
     89         push_up(x);
     90         t=x;  x=fa[x];
     91     }
     92 }
     93 
     94 void make_root(int x){  acc(x),splay(x),rev[x]^=1;  }
     95 
     96 void split(int x,int y){  make_root(x),acc(y),splay(y);  }
     97 
     98 void dfs(int no,int fat){
     99     fa[no]=fat;
    100     for(rint e=head[no];e;e=G[e].nxt)
    101         if(G[e].to!=fat)
    102             dfs(G[e].to,no);
    103 }
    104 
    105 int main(){
    106 //    freopen("temp.in","r",stdin);
    107     n=read();
    108     for(rint i=1,from,to;i<n;i++){
    109         from=read(),to=read();
    110         a_ed(from,to);
    111     }
    112     memset(mx,-inf,(n+1)<<2);
    113     for(rint i=1;i<=n;i++){
    114         val[i]=read();
    115         su[i]=mx[i]=val[i];
    116     }
    117     dfs(1,0);
    118     char opt[10];  int x,y;
    119     m=read();
    120     while(m--){
    121         scanf("%s",opt);
    122         x=read(),y=read();
    123         switch(opt[1]){
    124             case 'H':{
    125                 acc(x);
    126                 splay(x);
    127                 val[x]=y;
    128                 push_up(x);
    129                 break;
    130             }
    131             case 'M':{
    132                 split(x,y);
    133                 printf("%d
    ",mx[y]);
    134                 break;
    135             }
    136             default:{
    137                 split(x,y);
    138                 printf("%d
    ",su[y]);
    139                 break;
    140             }
    141         }
    142     }
    143     return 0;
    144 }
  • 相关阅读:
    CF1202F You Are Given Some Letters...
    CF1178E Archaeology
    PTA (Advanced Level) 1005 Spell It Right
    PTA (Advanced Level) 1004 Counting Leaves
    Qt5——从零开始的Hello World教程(Qt Creator)
    PTA (Advanced Level) 1003 Emergency
    PTA (Advanced Level) 1002 A+B for Polynomials
    HDU 1272 小希的迷宫
    FZU 2150 Fire Game
    HihoCoder
  • 原文地址:https://www.cnblogs.com/ZYBGMZL/p/7376254.html
Copyright © 2011-2022 走看看