• (WC2016模拟十八)Gangsters of Treeland


    HINT:

    $1leq N,Qleq 10^5$

    原题:CodeChef November Challenge 2013 - MONOPLOY

    题解:

    其实这题是【SDOI2017】树点涂色的弱化版。。。

    然后树点涂色这题甚至是[LOJ6022]【BZOJ3779】重组病毒的弱化版。。。

    首先题目中的距离就是求路径上不同颜色的数目;

    容易发现修改操作看起来很像LCT里的轻重边切换,那么以dfs序为下标建一颗线段树维护每个点到根节点的距离和,外面用一颗LCT维护,每次access轻重边切换的时候在线段树上修改即可。

    时间复杂度:$O(nlog^2n)$

    1A就是爽

    代码:

      1 #include<algorithm>
      2 #include<iostream>
      3 #include<cstring>
      4 #include<cstdio>
      5 #include<cmath>
      6 #include<queue>
      7 #define inf 2147483647
      8 #define eps 1e-9
      9 using namespace std;
     10 typedef long long ll;
     11 struct edge{
     12     int v,next;
     13 }a[200001];
     14 int n,q,u,v,x,tim=0,tot=0,head[100001],dep[100001],siz[100001],in[100001],out[100001],nmd[100001];
     15 char op[3];
     16 namespace sgt{
     17     struct node{
     18         ll v,laz;
     19     }t[500001];
     20     void pd(int u,int l,int r){
     21         if(t[u].laz){
     22             int mid=(l+r)/2;
     23             t[u*2].v+=t[u].laz*(mid-l+1);
     24             t[u*2].laz+=t[u].laz;
     25             t[u*2+1].v+=t[u].laz*(r-mid);
     26             t[u*2+1].laz+=t[u].laz;
     27             t[u].laz=0;
     28         }
     29     }
     30     void build(int l,int r,int u){
     31         if(l==r){
     32             t[u].v=dep[nmd[l]]-1;
     33             return;
     34         }
     35         int mid=(l+r)/2;
     36         build(l,mid,u*2);
     37         build(mid+1,r,u*2+1);
     38         t[u].v=t[u*2].v+t[u*2+1].v;
     39     }
     40     void updata(int l,int r,int u,int L,int R,ll v){
     41         if(L<=l&&r<=R){
     42             t[u].v+=v*(r-l+1);
     43             t[u].laz+=v;
     44             return;
     45         }
     46         int mid=(l+r)/2;
     47         pd(u,l,r);
     48         if(L<=mid)updata(l,mid,u*2,L,R,v);
     49         if(mid<R)updata(mid+1,r,u*2+1,L,R,v);
     50         t[u].v=t[u*2].v+t[u*2+1].v;
     51     }
     52     ll query(int l,int r,int u,int L,int R){
     53         if(L<=l&&r<=R){
     54             return t[u].v;
     55         }
     56         int mid=(l+r)/2;
     57         ll ret=0;
     58         pd(u,l,r);
     59         if(L<=mid)ret=query(l,mid,u*2,L,R);
     60         if(mid<R)ret+=query(mid+1,r,u*2+1,L,R);
     61         return ret;
     62     }
     63 }
     64 namespace lct{
     65     struct node{
     66         int son[2],fa,v;
     67     }t[200001];
     68     bool ntrt(int u){
     69         return t[t[u].fa].son[0]==u||t[t[u].fa].son[1]==u;
     70     }
     71     bool lr(int u){
     72         return t[t[u].fa].son[1]==u;
     73     }
     74     void rotate(int u){
     75         int f=t[u].fa,ff=t[f].fa,ch=lr(u);
     76         if(ntrt(f))t[ff].son[lr(f)]=u;
     77         t[f].son[ch]=t[u].son[ch^1];
     78         t[t[f].son[ch]].fa=f;
     79         t[u].son[ch^1]=f;
     80         t[f].fa=u;
     81         t[u].fa=ff;
     82     }
     83     void splay(int u){
     84         //printf("in splay %d %d
    ",u,t[u].fa);
     85         while(ntrt(u)){
     86             int f=t[u].fa;
     87             if(ntrt(f))rotate(lr(u)^lr(f)?f:u);
     88             rotate(u);
     89         }
     90     }
     91     int get(int u){
     92         while(t[u].son[0])u=t[u].son[0];
     93         return u;
     94     }
     95     void access(int u){
     96         for(int now=0;u;now=u,u=t[u].fa){
     97             //printf("%d %d
    ",u,now);
     98             splay(u);
     99             if(t[u].son[1]){
    100                 int x=get(t[u].son[1]);
    101                 sgt::updata(1,n,1,in[x],out[x],1);
    102             }
    103             if(now){
    104                 int x=get(now);
    105                 sgt::updata(1,n,1,in[x],out[x],-1);
    106             }
    107             t[u].son[1]=now;
    108         }
    109     }
    110 }
    111 void add(int u,int v){
    112     a[++tot].v=v;
    113     a[tot].next=head[u];
    114     head[u]=tot;
    115 }
    116 void dfs(int u,int fa,int dpt){
    117     dep[u]=dpt;
    118     siz[u]=1;
    119     in[u]=++tim;
    120     nmd[tim]=u;
    121     for(int tmp=head[u];tmp!=-1;tmp=a[tmp].next){
    122         int v=a[tmp].v;
    123         if(v!=fa){
    124             lct::t[v].fa=u;
    125             dfs(v,u,dpt+1);
    126             siz[u]+=siz[v];
    127         }
    128     }
    129     out[u]=tim;
    130 }
    131 int main(){
    132     memset(head,-1,sizeof(head));
    133     scanf("%d",&n);
    134     for(int i=1;i<n;i++){
    135         scanf("%d%d",&u,&v);
    136         u++,v++;
    137         add(u,v);
    138         add(v,u);
    139     }
    140     dfs(1,0,1);
    141     sgt::build(1,n,1);
    142     scanf("%d",&q);
    143     for(int i=1;i<=q;i++){
    144         scanf("%s%d",op,&x);
    145         x++;
    146         if(op[0]=='O')lct::access(x);
    147         else printf("%.8lf
    ",(double)sgt::query(1,n,1,in[x],out[x])/(double)(siz[x]));
    148     }
    149     return 0;
    150 }
  • 相关阅读:
    & 微信支付对比
    # MySQL性能优化技巧
    & mysql简单定时增量全量备份
    & Mysql高级总结
    python面向对象
    django虚拟环境的安装
    Python 内置函数
    Python列表解析式
    函数练习
    Python装饰器
  • 原文地址:https://www.cnblogs.com/dcdcbigbig/p/9777389.html
Copyright © 2020-2023  润新知