zoukankan      html  css  js  c++  java
  • [BZOJ3779]重组病毒(LCT+DFS序线段树)

    [BZOJ4817]树点涂色,只是多了换根操作,分类讨论下即可。

      1 #include<cstdio>
      2 #include<algorithm>
      3 #define lc ch[x][0]
      4 #define rc ch[x][1]
      5 #define ls (x<<1)
      6 #define rs (ls|1)
      7 #define lson ls,L,mid
      8 #define rson rs,mid+1,R
      9 #define rep(i,l,r) for (int i=(l); i<=(r); i++)
     10 #define For(i,x) for (int i=h[x],k; i; i=nxt[i])
     11 typedef long long ll;
     12 using namespace std;
     13 
     14 const int N=100010;
     15 char op[10];
     16 ll tag[N<<2],sm[N<<2];
     17 int n,m,u,v,x,rt,cnt,tim,rev[N],h[N],nxt[N<<1],to[N<<1];
     18 int L[N],R[N],dep[N],fa[N][20],ch[N][2],sz[N],f[N];
     19 void add(int u,int v){ to[++cnt]=v; nxt[cnt]=h[u]; h[u]=cnt; }
     20 
     21 inline int rd(){
     22     int x=0; char ch=getchar(); bool f=0;
     23     while (ch<'0' || ch>'9') f|=ch=='-',ch=getchar();
     24     while (ch>='0' && ch<='9') x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
     25     return f ? -x : x;
     26 }
     27 
     28 int jump(int x,int k){
     29     for (int i=18; ~i; i--) if (k&(1<<i)) x=fa[x][i]; return x;
     30 }
     31 
     32 void push(int x,int L,int R){
     33     if (!tag[x]) return;
     34     int mid=(L+R)>>1;
     35     sm[ls]+=tag[x]*(mid-L+1); tag[ls]+=tag[x];
     36     sm[rs]+=tag[x]*(R-mid); tag[rs]+=tag[x];
     37     tag[x]=0;
     38 }
     39 
     40 void mdf(int x,int L,int R,int l,int r,int k){
     41     if (L==l && r==R){ sm[x]+=1ll*k*(R-L+1); tag[x]+=k; return; }
     42     int mid=(L+R)>>1; push(x,L,R);
     43     if (r<=mid) mdf(lson,l,r,k);
     44     else if (l>mid) mdf(rson,l,r,k);
     45         else mdf(lson,l,mid,k),mdf(rson,mid+1,r,k);
     46     sm[x]=sm[ls]+sm[rs];
     47 }
     48 
     49 ll que(int x,int L,int R,int l,int r){
     50     if (L==l && r==R) return sm[x];
     51     int mid=(L+R)>>1; push(x,L,R);
     52     if (r<=mid) return que(lson,l,r);
     53     else if (l>mid) return que(rson,l,r);
     54         else return que(lson,l,mid)+que(rson,mid+1,r);
     55 }
     56 
     57 void dfs(int x){
     58     L[x]=++tim; dep[x]=dep[fa[x][0]]+1; sz[x]=1;
     59     rep(i,1,18) fa[x][i]=fa[fa[x][i-1]][i-1];
     60     mdf(1,1,n,L[x],L[x],dep[x]);
     61     For(i,x) if ((k=to[i])!=fa[x][0]) fa[k][0]=x,f[k]=x,dfs(k),sz[x]+=sz[k];
     62     R[x]=tim;
     63 }
     64 
     65 bool isrt(int x){ return (!f[x]) || (ch[f[x]][0]!=x && ch[f[x]][1]!=x); }
     66 void put(int x){ swap(lc,rc); rev[x]^=1; }
     67 void push(int x){ if (rev[x]) put(lc),put(rc),rev[x]=0; }
     68 void pd(int x){ if (!isrt(x)) pd(f[x]); push(x); }
     69 
     70 void rot(int x){
     71     int y=f[x],z=f[y],w=ch[y][1]==x;
     72     if (!isrt(y)) ch[z][ch[z][1]==y]=x;
     73     f[x]=z; f[y]=x; f[ch[x][w^1]]=y;
     74     ch[y][w]=ch[x][w^1]; ch[x][w^1]=y;
     75 }
     76 
     77 void splay(int x){
     78     pd(x);
     79     while (!isrt(x)){
     80         int y=f[x],z=f[y];
     81         if (!isrt(y)) (ch[z][1]==y)^(ch[y][1]==x) ? rot(x) : rot(y);
     82         rot(x);
     83     }
     84 }
     85 
     86 void work(int x,int k){
     87     if (rt==x) mdf(1,1,n,1,n,k);
     88     else if (L[rt]>=L[x] && L[rt]<=R[x]){
     89         int t=jump(rt,dep[rt]-dep[x]-1);
     90         if (L[t]>1) mdf(1,1,n,1,L[t]-1,k);
     91         if (R[t]<n) mdf(1,1,n,R[t]+1,n,k);
     92     }else mdf(1,1,n,L[x],R[x],k);
     93 }
     94 
     95 int find(int x){
     96     push(x);
     97     while (lc) x=lc,push(x);
     98     return x;
     99 }
    100 
    101 void access(int x){
    102     for (int y=0; x; y=x,x=f[x]){
    103         splay(x);
    104         if (rc) work(find(rc),1);
    105         if (y) work(find(y),-1);
    106         rc=y;
    107     }
    108 }
    109 
    110 void mkrt(int x){ access(x); splay(x); put(x); }
    111 
    112 int main(){
    113     freopen("bzoj3779.in","r",stdin);
    114     freopen("bzoj3779.out","w",stdout);
    115     n=rd(); m=rd();
    116     rep(i,2,n) u=rd(),v=rd(),add(u,v),add(v,u);
    117     dfs(1); rt=1;
    118     while (m--){
    119         scanf("%s",op); x=rd();
    120         if (op[2]=='L') access(x);
    121         if (op[2]=='C') mkrt(x),rt=x;
    122         if (op[2]=='Q'){
    123             if (rt==x) printf("%.10lf
    ",1.*que(1,1,n,1,n)/n);
    124             else if (L[rt]>=L[x] && L[rt]<=R[x]){
    125                 int t=jump(rt,dep[rt]-dep[x]-1);
    126                 ll res1=L[t]>1 ? que(1,1,n,1,L[t]-1) : 0;
    127                 ll res2=R[t]<n ? que(1,1,n,R[t]+1,n) : 0;
    128                 printf("%.10lf
    ",1.*(res1+res2)/(n-sz[t]));
    129             }else printf("%.10lf
    ",1.*que(1,1,n,L[x],R[x])/sz[x]);
    130         }
    131     }
    132     return 0;
    133 }
  • 相关阅读:
    桌面图标有蓝底
    创建与删除SQL约束或字段约束
    (转)ASP.NET(C#) 读取EXCEL ——另加解决日期问题
    ASP连接11种数据库的语法
    GridView 合并列、行类
    Office对应ContentType
    (解决办法)ASP.NET导出Excel,打开时提示“您尝试打开文件'XXX.xls'的格式与文件扩展名指定文件不一致
    (转)js判断只能输入数字或小数点
    vscode设置字体大小
    springsecurity+jwt实现登录
  • 原文地址:https://www.cnblogs.com/HocRiser/p/10300424.html
Copyright © 2011-2022 走看看