• Bzoj4817 [Sdoi2017]树点涂色


    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 301  Solved: 182

    Description

    Bob有一棵n个点的有根树,其中1号点是根节点。Bob在每个点上涂了颜色,并且每个点上的颜色不同。定义一条路
    径的权值是:这条路径上的点(包括起点和终点)共有多少种不同的颜色。Bob可能会进行这几种操作:
    1 x:
    把点x到根节点的路径上所有的点染上一种没有用过的新颜色。
    2 x y:
    求x到y的路径的权值。
    3 x y:
    在以x为根的子树中选择一个点,使得这个点到根节点的路径权值最大,求最大权值。
    Bob一共会进行m次操作
     

    Input

    第一行两个数n,m。
    接下来n-1行,每行两个数a,b,表示a与b之间有一条边。
    接下来m行,表示操作,格式见题目描述
    1<=n,m<=100000
     

    Output

    每当出现2,3操作,输出一行。
    如果是2操作,输出一个数表示路径的权值
    如果是3操作,输出一个数表示权值的最大值
     

    Sample Input

    5 6
    1 2
    2 3
    3 4
    3 5
    2 4 5
    3 3
    1 4
    2 4 5
    1 5
    2 4 5

    Sample Output

    3
    4
    2
    2

    HINT

     

    Source

    Bzoj3779 重组病毒 ←这个的弱化版

    树 线段树 LCT LCA

    基本上和上面那道题一样

    查询链上颜色树的时候做差分即可,$ ans=val(x)+val(y)-2*val(LCA(x,y))+1 $

      1 /*by SilverN*/
      2 #include<algorithm>
      3 #include<iostream>
      4 #include<cstring>
      5 #include<cstdio>
      6 #include<cmath>
      7 #include<vector>
      8 #define LL long long
      9 using namespace std;
     10 const int mxn=100010;
     11 int read(){
     12     int x=0,f=1;char ch=getchar();
     13     while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
     14     while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
     15     return x*f;
     16 }
     17 struct edge{
     18     int v,nxt;
     19 }e[mxn<<1];
     20 int hd[mxn],mct=0;
     21 void add_edge(int u,int v){
     22     e[++mct].v=v;e[mct].nxt=hd[u];hd[u]=mct;return;
     23 }
     24 namespace TC{
     25     struct node{
     26         int fa,top,son;
     27         int sz;
     28     }t[mxn];
     29     int dep[mxn],ind[mxn],out[mxn],dtime;
     30     int mp[mxn];
     31     void DFS(int u,int ff){
     32         dep[u]=dep[ff]+1;
     33         t[u].sz++;
     34         for(int i=hd[u],v;i;i=e[i].nxt){
     35             if(e[i].v==ff)continue;
     36             v=e[i].v;
     37             t[v].fa=u;
     38             DFS(v,u);
     39             t[u].sz+=t[v].sz;
     40             if(t[v].sz>t[t[u].son].sz)t[u].son=v;
     41         }
     42         return;
     43     }
     44     void DFS2(int u,int top){
     45         ind[u]=++dtime;
     46         mp[dtime]=u;
     47         t[u].top=top;
     48         if(t[u].son){
     49             DFS2(t[u].son,top);
     50             for(int i=hd[u];i;i=e[i].nxt){
     51                 if(e[i].v==t[u].son || e[i].v==t[u].fa)continue;
     52                 DFS2(e[i].v,e[i].v);
     53             }
     54         }
     55         out[u]=dtime;
     56         return;
     57     }
     58     int LCA(int x,int y){
     59         while(t[x].top!=t[y].top){
     60             if(dep[t[x].top]<dep[t[y].top])swap(x,y);
     61             x=t[t[x].top].fa;
     62         }
     63         if(dep[x]<dep[y])return x;
     64         else return y;
     65     }
     66 }
     67 int n,m,nowroot;
     68 struct SGT{
     69     #define lc rt<<1
     70     #define rc rt<<1|1
     71     struct node{
     72         LL smm,mk,mx;
     73     }t[mxn<<2];
     74     void pushup(int rt){
     75         t[rt].smm=t[lc].smm+t[rc].smm;
     76         t[rt].mx=max(t[lc].mx,t[rc].mx);
     77         return;
     78     }
     79     inline void PD(int l,int r,int rt){
     80         if(t[rt].mk){
     81             t[lc].mk+=t[rt].mk;
     82             t[rc].mk+=t[rt].mk;
     83             int mid=(l+r)>>1;
     84             t[lc].smm+=t[rt].mk*(LL)(mid-l+1);
     85             t[rc].smm+=t[rt].mk*(LL)(r-mid);
     86             t[lc].mx+=t[rt].mk;t[rc].mx+=t[rt].mk;
     87             t[rt].mk=0;
     88         }
     89         return;
     90     }
     91     void Build(int l,int r,int rt){
     92         if(l==r){
     93             t[rt].smm=t[rt].mx=TC::dep[TC::mp[l]];    return;
     94         }
     95         int mid=(l+r)>>1;
     96         Build(l,mid,lc);Build(mid+1,r,rc);
     97         pushup(rt);
     98         return;
     99     }
    100     void update(int L,int R,int v,int l,int r,int rt){
    101         if(L>R)return;
    102         if(L<=l && r<=R){
    103             t[rt].mk+=v;
    104             t[rt].smm+=(LL)v*(r-l+1);
    105             t[rt].mx+=v;
    106             return;
    107         }
    108         PD(l,r,rt);
    109         int mid=(l+r)>>1;
    110         if(L<=mid)update(L,R,v,l,mid,lc);
    111         if(R>mid)update(L,R,v,mid+1,r,rc);
    112         pushup(rt);
    113         return;
    114     }
    115     LL qmax(int L,int R,int l,int r,int rt){
    116         if(L>R)return -1e9;
    117         if(L<=l && r<=R){return t[rt].mx;}
    118         PD(l,r,rt);
    119         int mid=(l+r)>>1;
    120         LL res=-1e9;
    121         if(L<=mid)res=max(res,qmax(L,R,l,mid,lc));
    122         if(R>mid)res=max(res,qmax(L,R,mid+1,r,rc));
    123         return res;
    124     }
    125     LL qsum(int p,int l,int r,int rt){
    126         if(l==r){return t[rt].smm;}
    127         PD(l,r,rt);
    128         LL res=0;
    129         int mid=(l+r)>>1;
    130         if(p<=mid)res=qsum(p,l,mid,lc);
    131         else res=qsum(p,mid+1,r,rc);
    132         pushup(rt);
    133         return res;
    134     }
    135     void Q_UPD(int x,int v){
    136         using namespace TC;        
    137         update(ind[x],out[x],v,1,n,1);
    138         return;
    139     }
    140     LL Query(int x){
    141         using namespace TC;
    142 //        printf("___:%d
    ",x);
    143         int y=read();
    144         int tmp=TC::LCA(x,y);
    145         LL ans=qsum(ind[x],1,n,1)+qsum(ind[y],1,n,1)-2*qsum(ind[tmp],1,n,1)+1;
    146         printf("%lld
    ",ans);
    147         return ans;
    148     }
    149     LL Q_max(int x){
    150         using namespace TC;
    151         LL ans=0;
    152         ans=qmax(ind[x],out[x],1,n,1);
    153         printf("%lld
    ",ans);
    154         return ans;
    155     }
    156     #undef lc
    157     #undef rc
    158 }sgt;
    159 struct LCT{
    160     int ch[mxn][2],fa[mxn];
    161     bool rev[mxn];
    162     int st[mxn],top;
    163     inline bool isroot(int x){return (ch[fa[x]][0]!=x && ch[fa[x]][1]!=x);}
    164     void PD(int rt){
    165         if(rev[rt]){
    166             rev[ch[rt][0]]^=1;    rev[ch[rt][1]]^=1;
    167             swap(ch[rt][0],ch[rt][1]);
    168             rev[rt]^=1;
    169         }
    170         return;
    171     }
    172     void rotate(int x){
    173         int y=fa[x],z=fa[y],lc,rc;
    174         if(ch[y][0]==x)lc=0;else lc=1; rc=lc^1;
    175         if(!isroot(y)) ch[z][ch[z][1]==y]=x;
    176         fa[x]=z;fa[y]=x;
    177         fa[ch[x][rc]]=y;
    178         ch[y][lc]=ch[x][rc]; ch[x][rc]=y;
    179         return;
    180     }
    181     void Splay(int x){
    182         st[top=1]=x;
    183         for(int i=x;!isroot(i);i=fa[i])    st[++top]=fa[i];
    184         while(top)PD(st[top--]);
    185         while(!isroot(x)){
    186             int y=fa[x],z=fa[y];
    187             if(!isroot(y)){
    188                 if((ch[z][0]==y)^(ch[y][0]==x))rotate(x);
    189                 else rotate(y);
    190             }
    191             rotate(x);
    192         }
    193     }
    194     void access(int x){
    195         for(int y=0;x;x=fa[x]){
    196             Splay(x);
    197             if(ch[x][1]){
    198                 int now=ch[x][1];
    199                 PD(now);
    200                 while(ch[now][0]){now=ch[now][0];PD(now);}
    201                 sgt.Q_UPD(now,1);
    202             }
    203             if(y){
    204                 int now=y;
    205                 PD(now);
    206                 while(ch[now][0]){now=ch[now][0];PD(now);}
    207                 sgt.Q_UPD(now,-1);
    208             }
    209             ch[x][1]=y;
    210             y=x;
    211         }
    212         return;
    213     }
    214 /*    void mkroot(int x){
    215         access(x);Splay(x);
    216         rev[x]^=1;
    217         nowroot=x;
    218         return;
    219     }*/
    220 }LT;
    221 void solve(){
    222     int x,opt;
    223     while(m--){
    224         scanf("%d%d",&opt,&x);
    225         if(opt==1){LT.access(x);continue;}
    226         if(opt==2){sgt.Query(x);continue;}
    227         if(opt==3){sgt.Q_max(x);continue;}
    228 //        else Debug();
    229     }
    230     return;
    231 }
    232 int main(){
    233 //    freopen("paint1.in","r",stdin);
    234 //    freopen("out2.txt","w",stdout);
    235     int i,j;
    236     n=read();m=read();
    237     int u,v;
    238     for(i=1;i<n;i++){
    239         u=read();v=read();
    240         add_edge(u,v);add_edge(v,u);
    241     }
    242     TC::DFS(1,0);
    243     TC::DFS2(1,1);
    244     for(i=1;i<=n;i++) LT.fa[i]=TC::t[i].fa;    
    245     sgt.Build(1,n,1);
    246     solve();
    247     return 0;
    248 }
  • 相关阅读:
    VS2010 使用TeeChart画图控件
    程序猿接私活经验总结,来自csdn论坛语录
    锁(下)
    android4.4组件分析--service组件-bindService源代码分析
    黑客和敏捷开发
    编写你自己的单点登录(SSO)服务
    Cloudera impala简单介绍及安装具体解释
    ACdream群赛1112(Alice and Bob)
    八大排序算法总结
    垂死挣扎还是涅槃重生 -- Delphi XE5 公布会归来感想
  • 原文地址:https://www.cnblogs.com/SilverNebula/p/6728569.html
Copyright © 2020-2023  润新知