zoukankan      html  css  js  c++  java
  • 【Foreign】染色 [LCT][线段树]

    染色

    Time Limit: 20 Sec  Memory Limit: 256 MB

    Description

      

    Input

      

    Output

      

    Sample Input

      13
      0 1
      0 2
      1 11
      1 10
      1 9
      9 12
      2 5
      5 8
      2 4
      2 3
      4 6
      4 7
      7
      q 0
      O 4
      q 6
      q 2
      O 9
      q 9
      q 2

    Sample Output

      2.0000000000
      1.0000000000
      0.8571428571
      0.5000000000
      1.8571428571

    HINT

      

    Main idea

      询问x到根路径上不同颜色的个数,支持将x到根的路径上的点全部设为新的颜色。

    Solution

      我们将边两端的点颜色相同的边设为实边不同的设为虚边。那么一次新增颜色的操作显然就是LCT的access操作!access的时候恰是虚边和实边的转换。

      那么我们只要用线段树维护每个点到根的贡献,结合dfs序来实现子树加,每次在LCT进行access的时候进行+-1修改,然后询问的时候用区间求和求得答案即可。

    Code

      1 #include<iostream>
      2 #include<string>
      3 #include<algorithm>
      4 #include<cstdio>
      5 #include<cstring>
      6 #include<cstdlib>
      7 #include<ctime>
      8 #include<cmath>
      9 using namespace std;  
     10 typedef long long s64;
     11 const int ONE=1500001;
     12 
     13 int n,m,x,y;
     14 int pos[ONE],size[ONE],Dep[ONE],dfn[ONE],cnt;
     15 s64 res;
     16 char ch[5];
     17 
     18 int lc[ONE],rc[ONE],fa[ONE];
     19 
     20 int get()
     21 {    
     22         int res=1,Q=1;char c;
     23         while( (c=getchar())<48 || c>57 )
     24         if(c=='-')Q=-1;
     25         res=c-48;
     26         while( (c=getchar())>=48 && c<=57 )
     27         res=res*10+c-48;
     28         return res*Q;
     29 }
     30 
     31 namespace tree
     32 {
     33         int next[ONE],first[ONE],go[ONE],tot;
     34         
     35         void Add(int u,int v)
     36         {
     37             next[++tot]=first[u];    first[u]=tot;    go[tot]=v;
     38             next[++tot]=first[v];    first[v]=tot;    go[tot]=u;
     39         }
     40         
     41         void Dfs(int u,int father)
     42         {
     43             pos[u] = ++cnt; dfn[cnt] = u;
     44             size[u] = 1;
     45             for(int e=first[u];e;e=next[e])
     46             {
     47                 int v=go[e];
     48                 if(v==father) continue;
     49                 Dep[v] = Dep[u] + 1;
     50                 fa[v] = u;
     51                 Dfs(v,u);
     52                 size[u] += size[v]; 
     53             }
     54         }
     55 }
     56 
     57 namespace Seg
     58 {
     59         struct power
     60         {
     61             s64 add,value;
     62         }Node[ONE];
     63         
     64         void pushdown(int i,int Q)
     65         {
     66             if(Node[i].add)
     67             {
     68                 Node[i<<1].add+=Node[i].add;
     69                 Node[i<<1|1].add+=Node[i].add;
     70                 Node[i<<1].value+=Node[i].add*(Q-Q/2);
     71                 Node[i<<1|1].value+=Node[i].add*(Q/2);
     72                 Node[i].add=0;
     73             }
     74         }
     75         
     76         void Build(int i,int l,int r)
     77         {
     78             if(l==r)
     79             {
     80                 Node[i].value = Dep[dfn[l]];
     81                 return;
     82             }
     83             int mid=(l+r)>>1;
     84             Build(i<<1,l,mid);    Build(i<<1|1,mid+1,r);
     85             Node[i].value=Node[i<<1].value+Node[i<<1|1].value;
     86         }
     87         
     88         void Update(int i,int l,int r,int L,int R,int x)
     89         {
     90             if(L<=l && r<=R)
     91             {
     92                 Node[i].add+=x;
     93                 Node[i].value+=(s64)(r-l+1)*x;
     94                 return;
     95             }
     96             
     97             pushdown(i,r-l+1);
     98             int mid=(l+r)>>1;
     99             if(L<=mid) Update(i<<1,l,mid,L,R,x);
    100             if(mid+1<=R) Update(i<<1|1,mid+1,r,L,R,x);
    101             Node[i].value=Node[i<<1].value+Node[i<<1|1].value;
    102         }
    103         
    104         void Query(int i,int l,int r,int L,int R)
    105         {
    106             if(L<=l && r<=R)
    107             {
    108                 res+=Node[i].value;
    109                 return;
    110             }
    111             pushdown(i,r-l+1);
    112             int mid=(l+r)>>1;
    113             if(L<=mid) Query(i<<1,l,mid,L,R);
    114             if(mid+1<=R) Query(i<<1|1,mid+1,r,L,R);
    115         } 
    116 }
    117 
    118 namespace LCT
    119 {
    120         int is_real(int x)
    121         {
    122             return (lc[fa[x]]==x || rc[fa[x]]==x);
    123         }
    124         
    125         void Turn(int x)
    126         {
    127             int y=fa[x],z=fa[y];
    128             int b= x==lc[y] ? rc[x]:lc[x];
    129             
    130             fa[x]=z;    fa[y]=x;
    131             if(b) fa[b]=y;
    132             
    133             if(z)
    134             {
    135                 if(y==lc[z]) lc[z]=x;
    136                 else 
    137                 if(y==rc[z]) rc[z]=x;
    138             }
    139             
    140             if(x==lc[y]) rc[x]=y,lc[y]=b;
    141             else lc[x]=y,rc[y]=b;
    142         }
    143         
    144         void Splay(int x)
    145         {
    146             while(is_real(x))
    147             {
    148                 if(is_real(fa[x]))
    149                 {
    150                     if( (lc[fa[x]]==x) == (lc[fa[fa[x]]]==fa[x]) ) Turn(fa[x]);
    151                     else Turn(x);
    152                 }
    153                 Turn(x);
    154             }
    155         }
    156         
    157         int find_root(int x)
    158         {
    159             while(lc[x]) x=lc[x];
    160             return x;
    161         }
    162         
    163         void access(int x)
    164         {
    165             for(int p=x,q=0; p; q=p,p=fa[p])
    166             {
    167                 Splay(p);
    168                 if(rc[p])
    169                 {
    170                     int N=find_root(rc[p]);
    171                     Seg::Update(1,1,n,pos[N],pos[N]+size[N]-1,+1);
    172                 } 
    173                 rc[p]=q;
    174                 if(rc[p])
    175                 {
    176                     int N=find_root(rc[p]);
    177                     Seg::Update(1,1,n,pos[N],pos[N]+size[N]-1,-1);
    178                 }
    179             }
    180         }
    181 }
    182 
    183 int main()
    184 {
    185         n=get();
    186         for(int i=1;i<n;i++)
    187         {
    188             x=get();    y=get();
    189             x++;    y++;
    190             tree::Add(x,y);
    191         }
    192         tree::Dfs(1,0);
    193         Seg::Build(1,1,n);
    194         
    195         m=get();
    196         while(m--)
    197         {
    198             scanf("%s",ch);    x=get(); x++;
    199             if(ch[0]=='O')
    200             {
    201                 LCT::access(x);
    202             }
    203             else
    204             {
    205                 res=0;
    206                 Seg::Query(1,1,n,pos[x],pos[x]+size[x]-1);
    207                 printf("%.10lf
    ",(double)res/size[x]);
    208             }
    209         }
    210         
    211 }
    View Code
  • 相关阅读:
    面向机器学习的特征工程
    卷积可视化,图像理解,deepdream,风格迁移
    损失函数
    开源是如何支撑区块链技术发展的
    揭秘机密计算:弥补最后一个入侵 “漏洞”
    什么是超大规模数据中心?
    比特币是避险资产还是储备资产?
    区块链技术生态持续优化,五大趋势不容忽视
    物联网低功耗广域网(LPWAN)的比较
    碎片化是物联网快速发展的阻碍,也是机会
  • 原文地址:https://www.cnblogs.com/BearChild/p/6498133.html
Copyright © 2011-2022 走看看