zoukankan      html  css  js  c++  java
  • bzoj4817 [Sdoi2017]树点涂色

    传送门

    吐槽一波怎么今年的山东OI这么水……(B

    不难看出第一种操作就是LCT的access,那么每个点到根节点的颜色种数就是虚边数量+1,两点间颜色种数同理……

    第三种操作可以用把每个虚边挂着的点的子树权值全部+1的方式来维护,那么直接LCT+区间修改区间求max的线段树维护即可,复杂度$O(nlog^2 n)$。

      1 /**************************************************************
      2     Problem: 4817
      3     User: _Angel_
      4     Language: C++
      5     Result: Accepted
      6     Time:5500 ms
      7     Memory:21092 kb
      8 ****************************************************************/
      9 #include<cstdio>
     10 #include<cstring>
     11 #include<algorithm>
     12 #include<vector>
     13 #define isroot(x) ((x)->p==null||((x)!=(x)->p->ch[0]&&(x)!=(x)->p->ch[1]))
     14 #define dir(x) ((x)==(x)->p->ch[1])
     15 using namespace std;
     16 const int maxn=100010;
     17 struct node{node *ch[2],*p;}null[maxn];
     18 void dfs(int);
     19 int LCA(int,int);
     20 node *access(node*);
     21 node *getroot(node*);
     22 void splay(node*);
     23 void rot(node*,int);
     24 void modify(int,int,int);
     25 int query(int,int,int);
     26 int mx[maxn<<2]={0},lazy[maxn<<2]={0};
     27 vector<int>G[maxn];
     28 int f[maxn][20],d[maxn],dfn[maxn],finish[maxn],tim=0;
     29 int n,m,lgn=0,s,t,k,x,y;
     30 int main(){
     31     null->ch[0]=null->ch[1]=null->p=null;
     32     scanf("%d%d",&n,&m);
     33     for(int i=1;i<=n;i++)null[i].ch[0]=null[i].ch[1]=null[i].p=null;
     34     for(int i=1;i<n;i++){
     35         scanf("%d%d",&x,&y);
     36         G[x].push_back(y);
     37         G[y].push_back(x);
     38     }
     39     dfs(1);
     40     for(int j=1;j<=lgn;j++)for(int i=1;i<=n;i++)f[i][j]=f[f[i][j-1]][j-1];
     41     while(m--){
     42         scanf("%d%d",&k,&x);
     43         if(k==1)access(null+x);
     44         else if(k==2){
     45             scanf("%d",&y);
     46             s=t=dfn[x];
     47             int ans=query(1,n,1);
     48             s=t=dfn[y];
     49             ans+=query(1,n,1);
     50             s=t=dfn[LCA(x,y)];
     51             ans-=query(1,n,1)<<1;
     52             printf("%d
    ",ans+1);
     53         }
     54         else if(k==3){
     55             s=dfn[x];
     56             t=finish[x];
     57             printf("%d
    ",query(1,n,1)+1);
     58         }
     59     }
     60     return 0;
     61 }
     62 void dfs(int x){
     63     dfn[x]=++tim;
     64     d[x]=d[f[x][0]]+1;
     65     null[x].p=null+f[x][0];
     66     while((1<<lgn)<d[x])lgn++;
     67     for(int i=0;i<(int)G[x].size();i++)if(G[x][i]!=f[x][0]){
     68         f[G[x][i]][0]=x;
     69         dfs(G[x][i]);
     70     }
     71     finish[x]=tim;
     72     if(f[x][0]){
     73         s=dfn[x];
     74         t=finish[x];
     75         k=1;
     76         modify(1,n,1);
     77     }
     78 }
     79 int LCA(int x,int y){
     80     if(d[x]!=d[y]){
     81         if(d[x]<d[y])swap(x,y);
     82         for(int i=lgn;i>=0;i--)if(d[f[x][i]]>=d[y])x=f[x][i];
     83     }
     84     if(x==y)return x;
     85     for(int i=lgn;i>=0;i--)if(f[x][i]!=f[y][i]){
     86         x=f[x][i];
     87         y=f[y][i];
     88     }
     89     return f[x][0];
     90 }
     91 node *access(node *x){
     92     node *y=null;
     93     while(x!=null){
     94         splay(x);
     95         if(x->ch[1]!=null){
     96             node *u=x->ch[1];
     97             x->ch[1]=null;
     98             u=getroot(u);
     99             s=dfn[u-null];
    100             t=finish[u-null];
    101             k=1;
    102             modify(1,n,1);
    103         }
    104         if(y!=null){
    105             y=getroot(y);
    106             s=dfn[y-null];
    107             t=finish[y-null];
    108             k=-1;
    109             modify(1,n,1);
    110         }
    111         x->ch[1]=y;
    112         y=x;
    113         x=x->p;
    114     }
    115     return y;
    116 }
    117 node *getroot(node *x){
    118     splay(x);
    119     while(x->ch[0]!=null)x=x->ch[0];
    120     splay(x);
    121     return x;
    122 }
    123 void splay(node *x){
    124     while(!isroot(x)){
    125         if(isroot(x->p)){
    126             rot(x->p,dir(x)^1);
    127             break;
    128         }
    129         if(dir(x)==dir(x->p))rot(x->p->p,dir(x->p)^1);
    130         else rot(x->p,dir(x)^1);
    131         rot(x->p,dir(x)^1);
    132     }
    133 }
    134 inline void rot(node *x,int d){
    135     node *y=x->ch[d^1];
    136     if((x->ch[d^1]=y->ch[d])!=null)y->ch[d]->p=x;
    137     y->p=x->p;
    138     if(!isroot(x))x->p->ch[dir(x)]=y;
    139     (y->ch[d]=x)->p=y;
    140 }
    141 void modify(int l,int r,int rt){
    142     if(s<=l&&t>=r){
    143         mx[rt]+=k;
    144         lazy[rt]+=k;
    145         return;
    146     }
    147     int mid=(l+r)>>1;
    148     if(s<=mid)modify(l,mid,rt<<1);
    149     if(t>mid)modify(mid+1,r,rt<<1|1);
    150     mx[rt]=max(mx[rt<<1],mx[rt<<1|1])+lazy[rt];
    151 }
    152 int query(int l,int r,int rt){
    153     if(s<=l&&t>=r)return mx[rt];
    154     int mid=(l+r)>>1,ans=0;
    155     if(s<=mid)ans=max(ans,query(l,mid,rt<<1));
    156     if(t>mid)ans=max(ans,query(mid+1,r,rt<<1|1));
    157     return ans+lazy[rt];
    158 }
    View Code

    ps:如果没记错的话,这题应该是重组病毒那题的超级弱化版……

  • 相关阅读:
    java.lang.NoSuchMethodError
    asm相关内容想下载(包括 jar 包)
    Initialization of bean failed; nested exception is java.lang.NoClassDefFoundError: org/objectweb/asm/Type
    用Navicat连接mysql报错:2003-Can't connect to MySql server on '10.100.0.109'(10039)
    The type java.lang.reflect.AnnotatedElement cannot be resolved. It is indirectly referenced from required .class files
    The type java.lang.CharSequence cannot be resolved. It is indirectly referenced from required .class files
    交通测速方式
    卡口和电子警察的区别
    Myeclipse连接Mysql数据库时报错:Error while performing database login with the pro driver:unable
    在window上安装mysql
  • 原文地址:https://www.cnblogs.com/hzoier/p/6697963.html
Copyright © 2011-2022 走看看