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 }
  • 相关阅读:
    vue父子组件传参之ref
    新版chrome移动端踩坑
    vue动态绑定class 选中当前列表变色
    vue 利用computed对文章列表进行排序
    vue数组排序
    Vue+Koa2移动电商实战 (十一)前后端通讯和跨域处理
    jQuery基础知识--Form基础
    关于可变数组的一点小知识
    锋利的jQuery读书笔记---jQuery中动画
    锋利的jQuery读书笔记---jQuery中的事件
  • 原文地址:https://www.cnblogs.com/ZYBGMZL/p/7376254.html
Copyright © 2011-2022 走看看