zoukankan      html  css  js  c++  java
  • BZOJ 2959 长跑 (LCT+并查集)

    题面:BZOJ传送门

    当成有向边做的发现过不去样例,改成无向边就忘了原来的思路..

    因为成环的点一定都能取到,我们把它们压成一个新点,权值为环上所有点的权值和

    这样保证了图是一颗森林

    每次询问转化为,取出$a$到$b$这条链,求链上所有点的权值和

    这实际是一个不删边的动态维护边双的过程

    可以用$LCT$维护

    加入一条边$<x,y>$时,我们取出链$x,y$

    如果$x,y$原来不连通,把它们连上

    否则说明$x,y$原来就联通的,连上这条边会成环,把$x,y$这条链上的点全都压成一个点,用并查集维护

    每次$access$都在并查集里找父亲就行了

    维护权值的时候细节比较多

      1 #include <vector>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <algorithm>
      5 #define N1 150010
      6 #define M1 (N1<<1)
      7 #define il inline
      8 #define idx(X) (X-'a')
      9 using namespace std;
     10  
     11 char str[M1];
     12 int n,m,de;
     13 int a[N1],r[N1];
     14  
     15 struct Union{
     16 int fa[N1];
     17 int findfa(int x)
     18 {
     19     int pre,y=x; 
     20     if(!x) return 0;
     21     while(fa[y]!=y) y=fa[y]; 
     22     while(fa[x]!=y){ pre=fa[x]; fa[x]=y; x=pre; }
     23     return y;
     24 }
     25 }U;
     26 struct LCT{
     27 int ch[N1][2],fa[N1],rev[N1],sum[N1],stk[N1],tp;
     28 il int idf(int x){ return (ch[fa[x]][0]==x)?0:1;}
     29 il void pushup(int x){ sum[x]=sum[ch[x][0]]+sum[ch[x][1]]+a[x]; }
     30 il int isroot(int x){ return (ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x)?1:0; }
     31 il void revers(int x){ swap(ch[x][0],ch[x][1]),rev[x]^=1; }
     32 il void pushdown(int x)
     33 { 
     34     if(rev[x])  
     35     {
     36         if(ch[x][0]) revers(ch[x][0]);
     37         if(ch[x][1]) revers(ch[x][1]);
     38         rev[x]^=1;
     39     }
     40 }
     41 il void rot(int x)
     42 {
     43     int y=fa[x],ff=fa[y],px=idf(x),py=idf(y);
     44     if(!isroot(y)) ch[ff][py]=x; fa[x]=ff;
     45     fa[ch[x][px^1]]=y; ch[y][px]=ch[x][px^1];
     46     fa[y]=x; ch[x][px^1]=y;
     47     pushup(y),pushup(x);
     48 }
     49 void splay(int x)
     50 {
     51     int y=x; stk[++tp]=x;
     52     while(!isroot(y)){stk[++tp]=fa[y],y=fa[y];}
     53     while(tp){pushdown(stk[tp--]);}
     54     while(!isroot(x))
     55     {
     56         y=fa[x];
     57         if(isroot(y)) rot(x);
     58         else if(idf(y)==idf(x)) rot(y),rot(x);
     59         else rot(x),rot(x);
     60     }
     61 }
     62 void access(int x)
     63 {
     64     for(int y=0;x;y=x,fa[x]=U.findfa(fa[x]),x=fa[x])
     65         splay(x),ch[x][1]=y,pushup(x);
     66 }
     67 void mkroot(int x)
     68 {
     69     access(x);
     70     splay(x);
     71     revers(x);
     72 }
     73 int findroot(int x)
     74 {
     75     access(x); splay(x);
     76     while(ch[x][0]) pushdown(ch[x][0]),x=ch[x][0];
     77     splay(x); return x;
     78 }
     79 void split(int x,int y)
     80 {
     81     mkroot(x); 
     82     access(y);
     83     splay(y);
     84 }
     85 void dfs(int x,int root)
     86 {
     87     U.fa[x]=root; 
     88     if(ch[x][0]) dfs(ch[x][0],root);
     89     if(ch[x][1]) dfs(ch[x][1],root);
     90 }
     91 int link(int x,int y)
     92 {
     93     /*if(x==4&&y==1)
     94         de=1; */
     95     mkroot(x); access(y); splay(y);
     96     int f=findroot(y);
     97     if(f==x){ //merge
     98         dfs(f,f); a[f]=sum[f];
     99         ch[f][0]=ch[f][1]=0;
    100     }else{ //link
    101         fa[x]=y;
    102     }
    103 }
    104 int query(int x,int y)
    105 {
    106     split(x,y);
    107     if(findroot(y)!=x) return -1;
    108     else return sum[x];
    109 }
    110 }lct;
    111  
    112  
    113 int main()
    114 {
    115     scanf("%d%d",&n,&m);
    116     int i,j,A,B,x,y,v,fl,ans=0,id=0,de;
    117     for(i=1;i<=n;i++) 
    118         scanf("%d",&a[i]), lct.sum[i]=a[i], r[i]=a[i], U.fa[i]=i;
    119     while(m--)
    120     {
    121         scanf("%d%d%d",&fl,&A,&B);
    122         if(fl==1)
    123         { 
    124             x=U.findfa(A); y=U.findfa(B);
    125             lct.link(x,y); 
    126         }
    127         if(fl==2)
    128         { 
    129             x=U.findfa(A); lct.splay(x);
    130             lct.sum[x]+=B-r[A]; 
    131             a[x]+=B-r[A];
    132             r[A]=B;
    133         }
    134         if(fl==3)
    135         {
    136             x=U.findfa(A); y=U.findfa(B);  
    137             printf("%d
    ",lct.query(x,y));
    138         }
    139     }
    140     return 0;
    141 }
  • 相关阅读:
    Unity The Method Signature Matching Rule
    Unity The Property Matching Rule
    Unity The Type Matching Rule
    Unity The Custom Attribute Matching Rule
    Unity The Member Name Matching Rule
    Unity No Policies
    Unity The Return Type Matching Rule
    Unity The Parameter Type Matching Rule
    Unity The Namespace Matching Rule
    关于TSQL递归查询的(转)
  • 原文地址:https://www.cnblogs.com/guapisolo/p/10326209.html
Copyright © 2011-2022 走看看