zoukankan      html  css  js  c++  java
  • 洛谷3703 [SDOI2017] 树点染色 【LCT】【线段树】

    题目分析:

      操作一很明显等价于LCT上的access操作,操作二是常识,操作三转化到dfs序上求最大值也是常识。access的时候顺便在线段树中把对应部分-1,把右子树的子树+1即可。

    代码:

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 
      4 const int maxn = 102000;
      5 
      6 int num,n,m;
      7 
      8 vector <int> g[maxn];
      9 
     10 int f[maxn],dep[maxn],dfsin[maxn],dfsout[maxn];
     11 
     12 class SegmentTree{
     13 private:
     14     int data[maxn<<2],lazy[maxn<<2],maxx[maxn<<2];
     15     void push_down(int now){
     16     int L = (now<<1),R = (now<<1|1);
     17     data[L] += lazy[now]; maxx[L] += lazy[now]; lazy[L] += lazy[now];
     18     data[R] += lazy[now]; maxx[R] += lazy[now]; lazy[R] += lazy[now];
     19     lazy[now] = 0;
     20     }
     21 public:
     22     void Add(int now,int tl,int tr,int l,int r,int d){
     23     if(lazy[now]&&tl!=tr) push_down(now);
     24     if(tl >= l && tr <= r){
     25         data[now] += d; lazy[now] += d;maxx[now] += d; return;
     26     }
     27     if(tl > r || tr < l) return;
     28     int mid = (tl+tr)/2;
     29     Add(now<<1,tl,mid,l,r,d);
     30     Add(now<<1|1,mid+1,tr,l,r,d);
     31     maxx[now] = max(maxx[now<<1],maxx[now<<1|1]);
     32     }
     33     int Query(int now,int tl,int tr,int l,int r){
     34     if(lazy[now]&&tl!=tr) push_down(now);
     35     if(tl >= l && tr <= r) return maxx[now];
     36     if(tl > r || tr < l) return 0;
     37     int mid = (tl+tr)/2;
     38     int ans = max(Query(now<<1,tl,mid,l,r),Query(now<<1|1,mid+1,tr,l,r));
     39     maxx[now] = max(maxx[now<<1],maxx[now<<1|1]);
     40     return ans;
     41     }
     42 }T;
     43 
     44 class LinkCutTree{
     45 private:
     46     int ch[maxn][2],fa[maxn],data[maxn];
     47     stack <int> sta;
     48  
     49     int is_root(int now){return ch[fa[now]][0]!=now&&ch[fa[now]][1]!=now;}
     50     
     51     void r0(int now,int dr){
     52     int son = ch[now][dr],pa = fa[now],gp = fa[pa];
     53     int tag = is_root(pa);
     54     ch[pa][dr^1] = son; fa[son] = pa;
     55     ch[now][dr] = pa; fa[pa] = now; fa[now] = gp;
     56     if(tag == 1) return;
     57     if(ch[gp][0] == pa) ch[gp][0] = now;
     58     else ch[gp][1] = now;
     59     }
     60 
     61     void splay(int now){
     62     while(!is_root(now)){
     63         int pa = fa[now],gp = fa[pa];
     64         if(is_root(pa)){
     65         if(ch[pa][0] == now) r0(now,1);
     66         else r0(now,0);
     67         }else{
     68         if(ch[gp][0] == pa){
     69             if(ch[pa][0] == now) r0(pa,1),r0(now,1);
     70             else r0(now,0),r0(now,1);
     71         }else{
     72             if(ch[pa][0] == now) r0(now,1),r0(now,0);
     73             else r0(pa,0),r0(now,0);
     74         }
     75         }
     76     }
     77     }
     78 public:
     79     void access(int now){
     80     int p = now,last = 0;
     81     while(p != 0){
     82         splay(p);
     83         int zz = ch[p][1]; while(ch[zz][0]) zz = ch[zz][0];
     84         if(zz)T.Add(1,1,n,dfsin[zz],dfsout[zz],1);
     85         int lt = p; while(ch[lt][0]) lt = ch[lt][0];
     86         T.Add(1,1,n,dfsin[lt],dfsout[lt],-1);
     87         ch[p][1] = last;
     88         last = p; p = fa[p];
     89     }
     90     T.Add(1,1,n,1,n,1);
     91     }
     92     void BuildLCT(){
     93     for(int i=1;i<=n;i++) data[i] = dep[i];
     94     for(int i=1;i<=n;i++) fa[i] = f[i];
     95     }
     96 }LCT;
     97 
     98 void read(){
     99     scanf("%d%d",&n,&m);
    100     for(int i=1;i<n;i++){
    101     int u,v; scanf("%d%d",&u,&v);
    102     g[u].push_back(v); g[v].push_back(u);
    103     }
    104 }
    105 
    106 int RMQ[maxn<<1][20],app[maxn][2],euler[maxn<<1],nE;
    107 
    108 void dfs(int now,int fa,int dp){
    109     f[now] = fa; dep[now] = dp;
    110     euler[++nE] = now; app[now][0] = app[now][1] = nE;
    111     dfsin[now] = dfsout[now] = ++num;
    112     T.Add(1,1,n,dfsin[now],dfsin[now],dp);
    113     for(int i=0;i<g[now].size();i++){
    114     int p = g[now][i];
    115     if(p == fa) continue;
    116     dfs(p,now,dp+1);
    117     dfsout[now] = dfsout[p];
    118     euler[++nE] = now; app[now][1] = nE;
    119     }
    120 }
    121 
    122 void BuildRMQ(){
    123     for(int i=1;i<=nE;i++) RMQ[i][0] = euler[i];
    124     for(int k=1;(1<<k)<=nE;k++){
    125     for(int i=1;i<=nE;i++){
    126         if(i+(1<<k-1) > nE) {RMQ[i][k] = RMQ[i][k-1];continue;}
    127         if(dep[RMQ[i][k-1]] < dep[RMQ[i+(1<<k-1)][k-1]]){
    128         RMQ[i][k] = RMQ[i][k-1];
    129         }else RMQ[i][k] = RMQ[i+(1<<k-1)][k-1];
    130     }
    131     }
    132 }
    133 
    134 int QueryLCA(int u,int v){
    135     int fst = min(app[u][0],app[v][0]),sec = max(app[u][1],app[v][1]);
    136     int len = sec-fst+1,k = 0;
    137     while((1<<k+1) <= len) k++;
    138     if(dep[RMQ[fst][k]] < dep[RMQ[sec-(1<<k)+1][k]]) return RMQ[fst][k];
    139     else return RMQ[sec-(1<<k)+1][k];
    140 }
    141 
    142 void init(){
    143     dfs(1,0,1);
    144     BuildRMQ();
    145     LCT.BuildLCT();
    146 }
    147 
    148 void getdist(){
    149     int u,v; scanf("%d%d",&u,&v);
    150     int lca = QueryLCA(u,v);
    151     u = dfsin[u],v = dfsin[v],lca = dfsin[lca];
    152     int ans = T.Query(1,1,n,u,u)+T.Query(1,1,n,v,v);
    153     ans = ans - 2*T.Query(1,1,n,lca,lca) + 1;
    154     printf("%d
    ",ans);
    155 }
    156 
    157 void Query(){
    158     int u; scanf("%d",&u);
    159     int ans = T.Query(1,1,n,dfsin[u],dfsout[u]);
    160     printf("%d
    ",ans);
    161 }
    162 
    163 void work(){
    164     for(int i=1;i<=m;i++){
    165     int cas; scanf("%d",&cas);
    166     if(cas == 1){int x;scanf("%d",&x);LCT.access(x);}
    167     else if(cas == 2) getdist();
    168     else if(cas == 3) Query();
    169     }
    170 }
    171 
    172 int main(){
    173     read();
    174     init();
    175     work();
    176     return 0;
    177 }
  • 相关阅读:
    2.6 CMMI2级——供应商协议管理(Supplier Agreement Management)
    使用boch仿真器在x86 PC平台上搭建Linux0.11系统环境(windows下)
    java实现登录验证码
    Hadoop DBOutputFormat的使用
    史蒂芬·金《肖申克的救赎》读后感
    Change Base
    IOS深入学习(20)之Object modeling
    android对话框(Dialog)的使用方法
    郝萌主的微信公众号上线了
    Dell shareplex 与HVR数据复制软件
  • 原文地址:https://www.cnblogs.com/Menhera/p/9108135.html
Copyright © 2011-2022 走看看