zoukankan      html  css  js  c++  java
  • LCT 填坑系列

    清华冬令营 T1用了LCT 这个东西以前有写过 然而并不熟练 发现没了板子根本就不会写 只能填一填坑辣

    BZOJ 2843 LCT
      1 #include <bits/stdc++.h>
      2 #define N 30010
      3 #define ls c[x][0]
      4 #define rs c[x][1]
      5 using namespace std;
      6 
      7 inline int read()
      8 {
      9     int x=0,f=1; char ch=getchar();
     10     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
     11     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
     12     return x*f;
     13 }
     14 int n,m,val[N];
     15 struct link_cut_tree
     16 {
     17     int c[N][2],fa[N],sum[N];
     18     bool rev[N];
     19     bool isroot(int x)
     20     {
     21         return c[fa[x]][0]!=x&&c[fa[x]][1]!=x;
     22     }
     23     void updata(int x)
     24     {
     25         if(!x) return ;
     26         sum[x]=sum[c[x][0]]+sum[c[x][1]]+val[x];
     27     }
     28     void reverse(int x)
     29     {
     30         if(!x) return ;
     31         rev[x]^=1;
     32         swap(c[x][0],c[x][1]);
     33     }
     34     void pushdown(int x)
     35     {
     36         if(rev[x])
     37         {
     38             reverse(c[x][0]);
     39             reverse(c[x][1]);
     40             rev[x]=0;
     41         }
     42     }
     43     void rotate(int x)
     44     {
     45         int y=fa[x],z=fa[y],l=(c[y][1]==x),r=l^1;
     46         if(!isroot(y)) c[z][c[z][1]==y]=x;
     47         if(c[x][r]) fa[c[x][r]]=y;
     48         fa[y]=x;fa[x]=z;
     49         c[y][l]=c[x][r];c[x][r]=y;
     50         updata(y); updata(x);
     51     }
     52     void relax(int x)
     53     {
     54         if(!isroot(x)) relax(fa[x]);
     55         pushdown(x);
     56     }
     57     void splay(int x)
     58     {
     59         relax(x);
     60         while(!isroot(x))
     61         {
     62             int y=fa[x],z=fa[y];
     63             if(!isroot(y))
     64             {
     65                 if((c[y][0]==x)^(c[z][0]==y)) rotate(y);
     66                 else rotate(x);
     67             }
     68             rotate(x);
     69         }
     70     }
     71     void access(int x)
     72     {
     73         for(int p=0;x;p=x,x=fa[x])
     74         {
     75             splay(x); c[x][1]=p; if(p) fa[p]=x; updata(x);
     76         }
     77     }
     78     void makeroot(int x)
     79     {
     80         access(x); splay(x); 
     81         reverse(x);
     82     }
     83     void link(int x,int y)
     84     {
     85         makeroot(x); fa[x]=y;
     86     }
     87     int find(int x)
     88     {
     89         while(fa[x]) x=fa[x];
     90         return x;
     91     }
     92     int query(int x,int y)
     93     {
     94         makeroot(x); access(y); splay(y);
     95         return sum[y];
     96     }
     97 }T; 
     98 int main()
     99 {
    100     //freopen("read.in","r",stdin);
    101     //freopen("wro.out","w",stdout);
    102     n=read();for(int i=1;i<=n;i++) val[i]=read();
    103     m=read();while(m--)
    104     {
    105         char sd[100]; scanf("%s",sd);
    106         int u=read(),v=read();
    107         if(sd[0]=='e')
    108         {
    109             if(T.find(u)==T.find(v))
    110                 printf("%d
    ",T.query(u,v));
    111             else printf("impossible
    ");
    112         }
    113         if(sd[0]=='b')
    114         {
    115             if(T.find(u)==T.find(v))
    116                 printf("no
    ");
    117             else T.link(u,v),printf("yes
    ");
    118         }
    119         if(sd[0]=='p')
    120         {
    121             val[u]=v; T.access(u);
    122         }
    123     }
    124     return 0;
    125 }
    View Code

    LCT? 我是先用离线的树链剖分先A了这题 发现LCT 实现起来比树剖更短 而且稍快(但是你一个log(LCT) 跟 人家俩log(树剖)跑得差不多 是不是不太好

    不在意。。QAQ

    BZOJ 2843 树剖
      1 #include <bits/stdc++.h>
      2 
      3 using namespace std;
      4 
      5 inline int read()
      6 {
      7     int x=0,f=1;char ch=getchar();
      8     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
      9     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
     10     return x*f;
     11 }
     12 int st[30010],ee;
     13 struct edge
     14 {
     15     int u,v,next;
     16 }vs[60010];
     17 int vl[30010],Fa[30010],lastadd;
     18 struct que
     19 {
     20     int dps;
     21     int u,v,tp;
     22 }Q[100010];
     23 int getfa(int x){return (Fa[x]==x)? x: Fa[x]=getfa(Fa[x]);}
     24 inline void addedge(int u,int v)
     25 {
     26     vs[++ee].v=v;vs[ee].u=u;vs[ee].next=st[u];st[u]=ee;
     27 }
     28 int fa[30010],dep[30010],size[30010],son[30010],top[30010];
     29 int pl[30010],bl[30010],tree[30010<<2],n,m,vis[30010];
     30 void dfs1(int rt)
     31 {
     32     size[rt]=1; vis[rt]=1;
     33     for(int i=st[rt];i;i=vs[i].next)
     34     {
     35         if(fa[rt]==vs[i].v) continue;
     36         fa[vs[i].v]=rt;
     37         dep[vs[i].v]=dep[rt]+1;
     38         dfs1(vs[i].v);
     39         if(size[son[rt]]<size[vs[i].v])
     40             son[rt]=vs[i].v;
     41     }
     42 }
     43 void dfs2(int rt)
     44 {
     45     pl[rt]=++lastadd; bl[lastadd]=rt;
     46     vis[rt]=1;
     47     if(son[rt])
     48     {
     49         top[son[rt]]=top[rt];
     50         dfs2(son[rt]);
     51     }
     52     for(int i=st[rt];i;i=vs[i].next)
     53     {
     54         if(fa[rt]==vs[i].v||vs[i].v==son[rt]) continue;
     55         dfs2(vs[i].v);
     56     }
     57 }
     58 inline void updata(int rt)
     59 {
     60     tree[rt]=tree[rt<<1]+tree[rt<<1|1];
     61 }
     62 void built(int l,int r,int rt)
     63 {
     64     if(l==r)
     65     {
     66         tree[rt]=vl[bl[l]];
     67         return ;
     68     }
     69     int mid=(l+r)>>1;
     70     built(l,mid,rt<<1); built(mid+1,r,rt<<1|1);
     71     updata(rt);
     72 }
     73 int query(int L,int R,int l,int r,int rt)
     74 {
     75     if(L<=l&&r<=R) return tree[rt];
     76     int mid=(l+r)>>1;
     77     if(mid>=R) return query(L,R,l,mid,rt<<1);
     78     if(mid<L) return query(L,R,mid+1,r,rt<<1|1);
     79     return query(L,R,l,mid,rt<<1)+query(L,R,mid+1,r,rt<<1|1);
     80 }
     81 void modify(int x,int y,int l,int r,int rt)
     82 {
     83     if(l==r)
     84     {
     85         tree[rt]=y;
     86         return ;
     87     }
     88     int mid=(l+r)>>1;
     89     if(mid>=x) modify(x,y,l,mid,rt<<1);
     90     else modify(x,y,mid+1,r,rt<<1|1);
     91     updata(rt);
     92 }
     93 inline int cal(int u,int v)
     94 {
     95     int ans=0;
     96     int f1=top[u],f2=top[v];
     97     if(dep[f1]>dep[f2]) swap(u,v),swap(f1,f2);
     98     while(f1!=f2)
     99     {
    100         ans+=query(pl[f2],pl[v],1,n,1);
    101         v=fa[f2]; f2=top[v];
    102         if(dep[f1]>dep[f2]) swap(u,v),swap(f1,f2);
    103     }
    104     if(dep[u]>dep[v]) swap(u,v);
    105     ans+=query(pl[u],pl[v],1,n,1);
    106     return ans;
    107 }
    108 int main()
    109 {
    110     //freopen("read.in","r",stdin);
    111     //freopen("wro.out","w",stdout);
    112     n=read();
    113     for(int i=1;i<=n;i++) vl[i]=read(),Fa[i]=i;
    114     m=read();
    115     for(int i=1;i<=m;i++)
    116     {
    117         char sd[1000];
    118         scanf("%s",sd);
    119         int u=read(),v=read();
    120         if(sd[0]=='e')
    121         {
    122             Q[i].dps=1; Q[i].tp=0;
    123             if(getfa(u)!=getfa(v))
    124                 Q[i].tp=1;
    125         }
    126         else if(sd[0]=='b')
    127         {
    128             Q[i].dps=2;
    129             int f1=getfa(u),f2=getfa(v);
    130             if(f1!=f2)
    131             {
    132                 Q[i].tp=1;
    133                 Fa[f1]=f2;
    134                 addedge(u,v);addedge(v,u);
    135             }
    136         }
    137         else Q[i].dps=3;
    138         Q[i].u=u; Q[i].v=v;
    139     }
    140     for(int i=1;i<=n;i++) top[i]=i;
    141     //dfs1(1); dfs2(1);
    142     for(int i=1;i<=n;i++) if(!vis[i]) dfs1(i);
    143     memset(vis,0,sizeof vis);
    144     for(int i=1;i<=n;i++) if(!vis[i]) dfs2(i);
    145     built(1,n,1);
    146     for(int i=1;i<=m;i++)
    147     {
    148         if(Q[i].dps==2)
    149         {
    150             if(Q[i].tp==1) printf("yes
    ");
    151             else printf("no
    ");
    152         }
    153         else if(Q[i].dps==1)
    154         {
    155             if(Q[i].tp==1) printf("impossible
    ");
    156             else printf("%d
    ",cal(Q[i].u,Q[i].v));
    157         }
    158         else if(Q[i].dps==3)
    159             modify(pl[Q[i].u],Q[i].v,1,n,1);
    160     }
    161     return 0;
    162 }
    View Code

    注意点:: LCT中 0号节点也会用于更新树的值 要时刻维护其fa、c为0 否则就会爆掉!! 感谢 Cicada

    例:

    1     void rotate(int x)
    2     {
    3         int y=fa[x],z=fa[y],l=(c[y][1]==x),r=l^1;
    4         if(!isroot(y)) c[z][c[z][1]==y]=x;
    5         if(c[x][r])/*!!!*/ fa[c[x][r]]=y; /* EXCITING!!*/
    6         fa[y]=x;fa[x]=z;
    7         c[y][l]=c[x][r];c[x][r]=y;
    8         updata(y); updata(x);
    9     }
    BZOJ 4025
      1 #include <bits/stdc++.h>
      2 #define ls c[x][0]
      3 #define rs c[x][1]
      4 #define inf 0x7fffffff
      5 using namespace std;
      6 
      7 inline int read()
      8 {
      9     int x=0,f=1; char ch=getchar();
     10     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
     11     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
     12     return x*f;
     13 }
     14 struct events
     15 {
     16     int u,v,start,end;
     17 }E[200010];
     18 struct Mt
     19 {
     20     int bl,tp;
     21 }Gs[400010];
     22 int sign[200010],tot;
     23 inline int timcatch(Mt a)
     24 {
     25     return (a.tp==1)? E[a.bl].start: E[a.bl].end;
     26 }
     27 inline bool cmp(const Mt a,const Mt b)
     28 {
     29     return timcatch(a)==timcatch(b)? a.tp<b.tp:timcatch(a)<timcatch(b);
     30 }
     31 int n,m,tt,mxx,val[400010];
     32 struct link_cut_tree
     33 {
     34     int mi[400010],sum[400010],vl[400010];
     35     int c[400010][2],fa[400010],rev[400010];
     36     inline bool isroot(int x)
     37     {
     38         return c[fa[x]][0]!=x&&c[fa[x]][1]!=x;
     39     }
     40     inline void updata(int x)
     41     {
     42         mi[x]=x; sum[x]=1;
     43         if(ls)
     44         {
     45             if(val[mi[x]]>val[mi[ls]]) mi[x]=mi[ls];
     46             sum[x]+=sum[ls];
     47         }
     48         if(rs)
     49         {
     50             if(val[mi[x]]>val[mi[rs]]) mi[x]=mi[rs];
     51             sum[x]+=sum[rs];
     52         }
     53     }
     54     void rever(int x)
     55     {
     56         if(!x) return ;
     57         rev[x]^=1; swap(ls,rs);
     58     }
     59     void pushdown(int x)
     60     {
     61         if(rev[x])
     62         {
     63             rever(ls); rever(rs);
     64             rev[x]^=1;
     65         }
     66     }
     67     void rotate(int x)
     68     {
     69         int y=fa[x],z=fa[y],l=(c[y][1]==x),r=l^1;
     70         if(!isroot(y)) c[z][c[z][1]==y]=x;
     71         if(c[x][r]) fa[c[x][r]]=y;
     72         fa[y]=x; fa[x]=z;
     73         c[y][l]=c[x][r]; c[x][r]=y;
     74         updata(y); updata(x);
     75     }
     76     void relax(int x)
     77     {
     78         if(!isroot(x)) relax(fa[x]);
     79         pushdown(x);
     80     }
     81     void splay(int x)
     82     {
     83         relax(x);
     84         while(!isroot(x))
     85         {
     86             int y=fa[x],z=fa[y];
     87             if(!isroot(y))
     88             {
     89                 if((c[y][0]==x)^(c[z][0]==y)) rotate(y);
     90                 else rotate(x);
     91             }
     92             rotate(x);
     93         }
     94     }
     95     void access(int x)
     96     {
     97         for(int p=0;x;p=x,x=fa[x])
     98         {
     99             splay(x); c[x][1]=p; 
    100             if(p) fa[p]=x;
    101             updata(x);
    102         }
    103     }
    104     void makeroot(int x)
    105     {
    106         access(x); splay(x); rever(x);
    107     }
    108     void link(int x,int y)
    109     {
    110         makeroot(x); fa[x]=y;
    111     }
    112     void cut(int x,int y)
    113     {
    114         makeroot(x); access(y);splay(y);
    115         c[y][0]=fa[x]=0;
    116     }
    117 
    118     int find(int x)
    119     {
    120         while(fa[x]) x=fa[x]; return x;
    121     }
    122     void insert(int x)
    123     {
    124         sign[x]=1; link(E[x].u,x+n); link(E[x].v,x+n);
    125     }
    126     void delet(int x)
    127     {
    128         sign[x]=0; cut(E[x].u,x+n); cut(E[x].v,x+n);
    129     }
    130     void flod(int x,int y,int t)
    131     {
    132         makeroot(x); access(y);splay(y);
    133         if((sum[y]>>1)&1) delet(mi[y]-n),insert(t);
    134         else 
    135         {
    136             int x=mi[y];
    137             if(val[x]>val[t+n]) mxx=max(mxx,val[t+n]);
    138             else mxx=max(mxx,val[x]),delet(mi[y]-n),insert(t);
    139         }
    140     }
    141 }T;
    142 
    143 void doin(int x)
    144 {
    145     if(Gs[x].tp==-1&&sign[Gs[x].bl])
    146         T.delet(Gs[x].bl);
    147     if(Gs[x].tp==1&&!sign[Gs[x].bl])
    148     {
    149         if(T.find(E[Gs[x].bl].u)!=T.find(E[Gs[x].bl].v))
    150             T.insert(Gs[x].bl);
    151         else T.flod(E[Gs[x].bl].u,E[Gs[x].bl].v,Gs[x].bl);
    152     }
    153 }
    154 int main()
    155 {
    156     //freopen("read.in","r",stdin);
    157     //freopen("wro.out","w",stdout);
    158     n=read();m=read();tt=read();
    159     for(int i=1;i<=n;i++) val[i]=inf;
    160     for(int i=1;i<=m;i++)
    161     {
    162         E[i].u=read();E[i].v=read();
    163         E[i].start=read();
    164         E[i].end=read();
    165         Gs[++tot].bl=i; Gs[tot].tp=1;
    166         Gs[++tot].bl=i; Gs[tot].tp=-1;
    167         val[i+n]=E[i].end;
    168     }
    169     sort(Gs+1,Gs+1+tot,cmp);
    170     /*  for(int i=1;i<=tot;i++)
    171     {
    172         printf("%d %d %d %d
    ",E[Gs[i].bl].u,E[Gs[i].bl].v,Gs[i].tp,timcatch(Gs[i]));
    173     }  */
    174     for(int i=1,j=1;i<=tt;i++)
    175     {
    176         while(timcatch(Gs[j])<i&&j<=tot) doin(j),j++;
    177         //printf("%d ",mxx);
    178         if(mxx>=i) printf("No
    ");
    179         else printf("Yes
    ");
    180     }
    181 }
    View Code

    感谢 GhostReach

    发现当图中存在奇环时 就不再是二分图 那么在LCT上维护两个信息 边消失的时间 以及 从一个点到另一个点的距离

    每次按出现的时间顺序加入一条边

    1、 边的两个顶点 在两颗不同的树中—— 直接link

    2、 边的两个顶点 在同一颗树中

      (i)加入后形成奇环—— 更新‘no’ 持续的时间 并删去 环上 消失时间最早的边

      (ii)加入后形成偶环—— 直接删去 环上消失时间最早的边

    ps:LCT的信息在边上 新开点维护

    BZOJ 3091
      1 #include <bits/stdc++.h>
      2 #define ls c[x][0]
      3 #define rs c[x][1]
      4 using namespace std;
      5 typedef long long ll;
      6 inline int read()
      7 {
      8     int x=0,f=1; char ch=getchar();
      9     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
     10     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
     11     return x*f;
     12 }
     13 int n,m;
     14 ll val[50010];
     15 ll gcd(ll a,ll b)
     16 {
     17     return (a%b)? gcd(b,a%b): b;
     18 }
     19 struct link_cut_tree
     20 {
     21     int fa[50010],c[50010][2],add[50010];
     22     ll sum1[50010],sum2[50010],sumE1[50010],sumE2[50010],sumP[50010],sumV[50010];
     23     bool rev[50010];
     24     inline bool isroot(int x)
     25     {
     26         return c[fa[x]][0]!=x&&c[fa[x]][1]!=x;
     27     }
     28     void reverse(int x)
     29     {
     30         if(!x) return ;
     31         rev[x]^=1; swap(ls,rs);
     32         swap(sum2[x],sum1[x]);
     33         swap(sumE1[x],sumE2[x]);
     34     }
     35     void adds(int x,int y)
     36     {
     37         if(!x) return;
     38         sumV[x]+=sumP[x]*y;
     39         sum1[x]+=y*(sumP[x]+1)*sumP[x]/2;
     40         sum2[x]+=y*(sumP[x]+1)*sumP[x]/2;
     41         sumE1[x]+=((sumP[x]+1)*(sumP[x]+1)*(sumP[x])/2-(sumP[x]*2+1)*(sumP[x]+1)*(sumP[x])/6)*y;
     42         sumE2[x]+=((sumP[x]+1)*(sumP[x]+1)*(sumP[x])/2-(sumP[x]*2+1)*(sumP[x]+1)*(sumP[x])/6)*y;
     43         val[x]+=y;add[x]+=y;
     44     }
     45     void pushdown(int x)
     46     {
     47         if(!x) return ;
     48         if(add[x])
     49         {
     50             adds(ls,add[x]); adds(rs,add[x]); add[x]=0;
     51         }
     52         if(rev[x])
     53         {
     54             reverse(ls); reverse(rs); rev[x]^=1;
     55         }
     56     }
     57     void updata(int x)
     58     {
     59         if(!x) return ;
     60         sumP[x]=1;
     61         if(ls) sumP[x]+=sumP[ls];
     62         if(rs) sumP[x]+=sumP[rs];
     63         sumV[x]=val[x];
     64         if(ls) sumV[x]+=sumV[ls];
     65         if(rs) sumV[x]+=sumV[rs];
     66         sum1[x]=(sumP[ls]+1)*val[x];
     67         if(ls) sum1[x]+=sum1[ls];
     68         if(rs) sum1[x]+=(sumV[rs]*(sumP[ls]+1))+sum1[rs];
     69         sum2[x]=(sumP[rs]+1)*val[x];
     70         if(ls) sum2[x]+=(sumV[ls]*(sumP[rs]+1))+sum2[ls];
     71         if(rs) sum2[x]+=sum2[rs];
     72         sumE1[x]=val[x]*(sumP[ls]+1)*(sumP[rs]+1);
     73         if(ls) sumE1[x]+=sumE1[ls]+sum1[ls]*(sumP[rs]+1);
     74         if(rs) sumE1[x]+=sumE1[rs]+sum2[rs]*(sumP[ls]+1);
     75         sumE2[x]=val[x]*(sumP[ls]+1)*(sumP[rs]+1);
     76         if(ls) sumE2[x]+=sumE2[ls]+sum1[ls]*(sumP[rs]+1);
     77         if(rs) sumE2[x]+=sumE2[rs]+sum2[rs]*(sumP[ls]+1);
     78     }
     79     void relax(int x)
     80     {
     81         if(!isroot(x)) relax(fa[x]);
     82         pushdown(x);
     83     }
     84     void rotate(int x)
     85     {
     86         int y=fa[x],z=fa[y],l=c[y][1]==x,r=l^1;
     87         if(!isroot(y)) c[z][c[z][1]==y]=x;
     88         if(c[x][r]) fa[c[x][r]]=y;
     89         fa[x]=z; fa[y]=x;
     90         c[y][l]=c[x][r]; c[x][r]=y;
     91         updata(y); updata(x);
     92     }
     93     void splay(int x)
     94     {
     95         relax(x);
     96         while(!isroot(x))
     97         {
     98             int y=fa[x],z=fa[y];
     99             if(!isroot(y))
    100             {
    101                 if((c[y][0]==x)^(c[z][0]==y)) rotate(y);
    102                 else rotate(x);
    103             }
    104             rotate(x);
    105         }
    106     }
    107     void access(int x)
    108     {
    109         for(int p=0;x;p=x,x=fa[x])
    110         {
    111             splay(x); c[x][1]=p; if(p) fa[p]=x; updata(x);
    112         }
    113     }
    114     void makeroot(int x)
    115     {
    116         access(x); splay(x); reverse(x);
    117     }
    118     int find(int x)
    119     {
    120         while(fa[x]) x=fa[x];
    121         return x;
    122     }
    123     void link(int x,int y)
    124     {
    125         makeroot(x); fa[x]=y;
    126     }
    127     void cut(int x,int y)
    128     {
    129         makeroot(x); access(y); splay(y);
    130         if(sumP[y]!=2) return;
    131         c[y][0]=fa[x]=0;
    132         updata(y);
    133     }
    134     void addval(int x,int y,int z)
    135     {
    136         makeroot(x); access(y); splay(y);
    137         adds(y,z);
    138     }
    139     void query(int x,int y)
    140     {
    141         makeroot(x); access(y); splay(y);
    142         ll tmp=gcd(sumE2[y],sumP[y]*(sumP[y]+1)>>1);
    143         printf("%lld/%lld
    ",sumE2[y]/tmp,(sumP[y]*(sumP[y]+1)>>1)/tmp);
    144     }
    145 }T;
    146 int main()
    147 {
    148     //freopen("read.in","r",stdin);
    149     //freopen("wro.in","w",stdout);
    150     n=read();m=read();
    151     for(int i=1;i<=n;i++) val[i]=read();
    152     for(int i=1;i<n;i++)
    153     {
    154         int u=read(),v=read();
    155         T.link(u,v); 
    156     }
    157     for(int i=1;i<=m;i++)
    158     {
    159         int tp=read();
    160         if(tp==1)
    161         {
    162             int u=read(),v=read();
    163             if(T.find(u)!=T.find(v)) continue;
    164             T.cut(u,v);
    165         }
    166         if(tp==2)
    167         {
    168             int u=read(),v=read();
    169             if(T.find(u)==T.find(v)) continue;
    170             T.link(u,v);
    171         }
    172         if(tp==3)
    173         {
    174             int u=read(),v=read(),z=read();
    175             if(T.find(u)!=T.find(v)) continue;
    176             T.addval(u,v,z);
    177         }
    178         if(tp==4)
    179         {
    180             int u=read(),v=read();
    181             if(T.find(u)!=T.find(v)) printf("-1
    ");
    182             else T.query(u,v);
    183         }
    184     }
    185 }
    View Code

    需要推一点点式子

    ps: 我好naive啊 lct上打标记的技巧 好像有点神奇啊 感谢:AwD

    打标记:

     1     void do_with_tag(**  **,**  **)
     2     {
     3         **********//do anything you like
     4         make_tag_with_ls;
     5         make_tag_with_rs;
     6     }
     7     void pushdown(** **)
     8     {
     9         if(there_is_tag)
    10         {
    11             do_with_tag(ls);
    12             do_with_tag(rs);
    13             delete_the_tag;
    14         }
    15     }
    16     //这里的tag 是这个节点上有信息需要被下传 
    17     //跟我以前打过的标记都不一样QAQ 坑了好久

     这题的dmk

     1 #include <bits/stdc++.h>
     2 #define N 50000
     3 #define M 50000
     4 using namespace std;
     5 
     6 int main()
     7 {
     8     freopen("read.in","w",stdout);
     9     srand(time(0));
    10     printf("%d
    ",N);printf("%d
    ",M);
    11     for(int i=1;i<=N;i++) printf("%d ",rand()*rand()%1000000); printf("
    ");
    12     for(int i=2;i<=N;i++)
    13     {
    14         int x=rand()%(i-1)+1;
    15         printf("%d %d
    ",i,x);
    16     }
    17     
    18     for(int i=1;i<=M;i++)
    19     {
    20         int tx=rand()%4+1;  printf("%d ",tx);
    21         if(tx==1||tx==2||tx==4) printf("%d %d
    ",rand()%N+1,rand()%N+1);
    22         if(tx==3) printf("%d %d %d
    ",rand()%N+1,rand()%N+1,rand()*rand()%1000000);
    23     }
    24 }
    View Code
    BZOJ 2157
      1 #include <bits/stdc++.h>
      2 #define inf 0x7fffffff
      3 #define ls c[x][0]
      4 #define rs c[x][1]
      5 #define int long long
      6 using namespace std;
      7 
      8 inline int read()
      9 {
     10     int x=0,f=1; char ch=getchar();
     11     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
     12     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
     13     return x*f;
     14 }
     15 int n,val[60010],m;
     16 struct link_cut_tree
     17 {
     18     int c[60010][2],fa[60010];
     19     int mx[60010],mi[60010],sum[60010],rev[60010],tbk[60010];
     20     inline bool isroot(int x)
     21     {
     22         return c[fa[x]][0]!=x&&c[fa[x]][1]!=x;
     23     }
     24     inline void updata(int x)
     25     {
     26         if(!x) return;
     27         mx[x]=max(mx[ls],mx[rs]);
     28         mi[x]=min(mi[ls],mi[rs]);
     29         if(x>n)mx[x]=max(mx[x],val[x]);
     30         if(x>n)mi[x]=min(mi[x],val[x]);
     31         sum[x]=sum[ls]+sum[rs]+val[x];
     32     }
     33     inline void reverse(int x)
     34     {
     35         if(!x) return ;
     36         rev[x]^=1; swap(ls,rs);
     37     }
     38     inline void turnback(int x)
     39     {
     40         if(!x) return;
     41         sum[x]=-sum[x];val[x]=-val[x];
     42         swap(mi[x],mx[x]);
     43         mi[x]=-mi[x];mx[x]=-mx[x];
     44         tbk[x]^=1;
     45     }
     46     inline void pushdown(int x)
     47     {
     48         if(!x) return ;
     49         if(rev[x])
     50         {
     51             reverse(ls); reverse(rs); rev[x]^=1;
     52         }
     53         if(tbk[x])
     54         {
     55             tbk[x]=0; turnback(ls); turnback(rs); 
     56         }
     57     }
     58     void relax(int x)
     59     {
     60         if(!isroot(x)) relax(fa[x]);
     61         pushdown(x);
     62     }
     63     void rotate(int x)
     64     {
     65         int y=fa[x],z=fa[y],l=c[y][1]==x,r=l^1;
     66         if(!isroot(y)) c[z][c[z][1]==y]=x;
     67         if(c[x][r]) fa[c[x][r]]=y;
     68         fa[x]=z; fa[y]=x;
     69         c[y][l]=c[x][r]; c[x][r]=y;
     70         updata(y); updata(x);
     71     }
     72     void splay(int x)
     73     {
     74         relax(x);
     75         while(!isroot(x))
     76         {
     77             int y=fa[x],z=fa[y];
     78             if(!isroot(y))
     79             {
     80                 if((c[y][0]==x)^(c[z][0]==y)) rotate(y);
     81                 else rotate(x);
     82             }
     83             rotate(x);
     84         }
     85     }
     86     void access(int x)
     87     {
     88         for(int p=0;x;p=x,x=fa[x])
     89         {
     90             splay(x); c[x][1]=p; if(p) fa[p]=x; updata(x);
     91         }
     92     }
     93     void makeroot(int x)
     94     {
     95         access(x); splay(x); reverse(x);
     96     }
     97     void modify1(int x,int y)
     98     {
     99         makeroot(x); access(x); splay(x);
    100         val[x]=y; updata(x);
    101     }
    102     void modify2(int x,int y)
    103     {
    104         makeroot(x); access(y); splay(y);
    105         turnback(y);
    106     }
    107     inline void query(int x,int y,int tp)
    108     {
    109         makeroot(x); access(y); splay(y);
    110         if(tp==1) printf("%lld
    ",mi[y]);
    111         if(tp==2) printf("%lld
    ",mx[y]);
    112         if(tp==3) printf("%lld
    ",sum[y]);
    113     }
    114     inline void link(int x,int y)
    115     {
    116         makeroot(x); fa[x]=y;
    117     }
    118 }T;
    119 signed main()
    120 {
    121     //freopen("read.in","r",stdin);
    122     //freopen("wro.in","w",stdout);
    123     n=read();
    124     T.mx[0]=-inf; T.mi[0]=inf;
    125     for(int i=1;i<n;i++)
    126     {
    127         T.mx[i]=-inf;
    128         T.mi[i]=inf;
    129         int u=read()+1,v=read()+1,w=read();
    130         T.link(u,i+n); T.link(v,i+n);
    131         T.mx[i+n]=T.mi[i+n]=T.sum[i+n]=val[i+n]=w;
    132     }
    133     m=read();
    134     for(int i=1;i<=m;i++)
    135     {
    136         char sd[10]; scanf("%s",sd);
    137         int u=read(),v=read();
    138         if(sd[0]=='S') T.query(u+1,v+1,3);
    139         if(sd[0]=='M'&&sd[1]=='I') T.query(u+1,v+1,1);
    140         if(sd[0]=='M'&&sd[1]=='A') T.query(u+1,v+1,2);
    141         if(sd[0]=='N') T.modify2(u+1,v+1);
    142         if(sd[0]=='C') T.modify1(u+n,v);
    143         //for(int j=n+1;j<=n+n-1;j++) printf("%d ",val[j]);
    144     }
    145 }
    View Code

    生无可恋QAQ 这种题。。。。WA了一个多小时

    还是维护信息时要仔细

    BZOJ 
      1 #include <bits/stdc++.h>
      2 #define ls c[x][0]
      3 #define rs c[x][1]
      4 using namespace std;
      5 
      6 inline int read()
      7 {
      8     int x=0,f=1; char ch=getchar();
      9     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
     10     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
     11     return x*f;
     12 }
     13 int n,m,c,k,val[10010],colnum[10010][11];
     14 map <int,int> M[10010];
     15 struct link_cut_tree
     16 {
     17     int fa[10010],c[10010][2],mx[10010],sz[10010];
     18     bool rev[10010];
     19     inline bool isroot(int x)
     20     {
     21         return c[fa[x]][0]!=x&&c[fa[x]][1]!=x;
     22     }
     23     void reverse(int x)
     24     {
     25         if(!x) return ;
     26         rev[x]^=1; swap(ls,rs);
     27     }
     28     void pushdown(int x)
     29     {
     30         if(!x) return ;
     31         if(rev[x])
     32         {
     33             reverse(ls); reverse(rs); rev[x]^=1;
     34         }
     35     }
     36     void updata(int x)
     37     {
     38         if(!x) return ;
     39         mx[x]=val[x];sz[x]=1;
     40         if(ls) mx[x]=max(mx[x],mx[ls]),sz[x]+=sz[ls];
     41         if(rs) mx[x]=max(mx[x],mx[rs]),sz[x]+=sz[rs];
     42     }
     43     void relax(int x)
     44     {
     45         if(!isroot(x)) relax(fa[x]);
     46         pushdown(x);
     47     }
     48     void rotate(int x)
     49     {
     50         int y=fa[x],z=fa[y],l=c[y][1]==x,r=l^1;
     51         if(!isroot(y)) c[z][c[z][1]==y]=x;
     52         if(c[x][r]) fa[c[x][r]]=y;
     53         fa[x]=z; fa[y]=x;
     54         c[y][l]=c[x][r]; c[x][r]=y;
     55         updata(y); updata(x);
     56     }
     57     void splay(int x)
     58     {
     59         relax(x);
     60         while(!isroot(x))
     61         {
     62             int y=fa[x],z=fa[y];
     63             if(!isroot(y))
     64             {
     65                 if((c[y][0]==x)^(c[z][0]==y)) rotate(y);
     66                 else rotate(x);
     67             }
     68             rotate(x);
     69         }
     70     }
     71     void access(int x)
     72     {
     73         for(int p=0;x;p=x,x=fa[x])
     74         {
     75             splay(x); c[x][1]=p; if(p) fa[p]=x; updata(x);
     76         }
     77     }
     78     void makeroot(int x)
     79     {
     80         access(x); splay(x); reverse(x);
     81     }
     82     int find(int x)
     83     {
     84         while(fa[x]) x=fa[x];
     85         return x;
     86     }
     87     void link(int x,int y)
     88     {
     89         makeroot(x); fa[x]=y;
     90     }
     91     int cut(int x,int y)
     92     {
     93         makeroot(x); access(y); splay(y);
     94         if(sz[y]!=2) return 0;
     95         c[y][0]=fa[x]=0;
     96         updata(y);
     97         return 1;
     98     }
     99     void addval(int x,int z)
    100     {
    101         splay(x);
    102         val[x]=z; mx[x]=z; updata(x);
    103     }
    104     void query(int x,int y)
    105     {
    106         makeroot(x); access(y); splay(y);
    107         printf("%d
    ",mx[y]);
    108     }
    109 }T[11];
    110 
    111 int main()
    112 {
    113     //freopen("read.in","r",stdin);
    114     //freopen("wro.in","w",stdout);
    115     n=read();m=read();c=read();k=read();
    116     for(int i=1;i<=n;i++) val[i]=read();
    117     for(int i=1;i<=m;i++)
    118     {
    119         int u=read(),v=read(),w=read()+1;
    120         T[w].link(u,v);
    121         M[u][v]=w; M[v][u]=w;
    122         colnum[u][w]++;
    123         colnum[v][w]++;
    124     }
    125     for(int i=1;i<=k;i++)
    126     {
    127         int tp=read(),x=read(),y=read();
    128         if(tp==0) for(int j=1;j<=c;j++) T[j].addval(x,y);
    129         if(tp==1) 
    130         {
    131             int g=M[x][y],kg=read()+1;
    132             if(!g) {printf("No such edge.
    "); continue;}
    133             if(g==kg){printf("Success.
    "); continue;}
    134             if(colnum[x][kg]>=2||colnum[y][kg]>=2)
    135             {
    136                 printf("Error 1.
    "); continue;
    137             }
    138             if(T[kg].find(x)==T[kg].find(y))
    139             {
    140                 printf("Error 2.
    "); continue;
    141             }
    142             printf("Success.
    ");
    143             T[g].cut(x,y); T[kg].link(x,y);
    144             M[x][y]=kg; M[y][x]=kg;
    145             colnum[x][g]--;colnum[y][g]--;
    146             colnum[x][kg]++; colnum[y][kg]++;
    147         }
    148         if(tp==2)
    149         {
    150             int g=read(); x++;
    151             if(T[x].find(g)!=T[x].find(y))
    152                 printf("-1
    ");
    153             else T[x].query(g,y);
    154         }
    155     }
    156     return 0;
    157 }
    View Code

    多种颜色 于是维护10棵LCT 暴力去修改 冷静地开10000个MAP (假装不会出事)这种做法讲讲道理是可以被卡掉的QAQ

    ps: 为什么我的LCT 常数这么大

    BZOJ 2759
      1 #include <bits/stdc++.h>
      2 #define N 30010
      3 #define ls c[x][0]
      4 #define rs c[x][1]
      5 #define mod 10007
      6 using namespace std;
      7 typedef long long ll;
      8 inline int read()
      9 {
     10     int x=0,f=1; char ch=getchar();
     11     while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();}
     12     while(ch>='0'&&ch<='9'){x=x*10+ch-'0'; ch=getchar();}
     13     return x*f;
     14 }
     15 int exgcd(int a,int b,int &x,int &y)
     16 {
     17     if(b==0){x=1;y=0;return a;}
     18     int r=exgcd(b,a%b,x,y);
     19     int t=x;x=y; y=t-a/b*y;
     20     return r;
     21 }
     22 inline int inv(int x)
     23 {
     24     int X,Y; exgcd((x%mod+mod)%mod,mod,X,Y);
     25     return (X%mod+mod)%mod;
     26 }
     27 int n,m,fa[N],vis[N],tim;
     28 struct link_cut_tree
     29 {
     30     int fa[N],c[N][2],k[N],b[N],sf[N],rev[N];
     31     struct fcl
     32     {
     33         int k,b;
     34         int f(int x){return (k*x+b)%mod;}
     35     }sum[N],val[N];
     36     friend fcl operator+(fcl a,fcl b)
     37     {
     38         fcl tmp;
     39         tmp.k=(a.k*b.k)%mod;
     40         tmp.b=(b.b+b.k*a.b%mod)%mod;
     41         return tmp;
     42     }
     43     inline bool isroot(int x)
     44     {
     45         return c[fa[x]][0]!=x&&c[fa[x]][1]!=x;
     46     }
     47     inline void updata(int x)
     48     {
     49         if(!x) return;
     50         sum[x]=val[x];
     51         if(ls) sum[x]=sum[ls]+sum[x];
     52         if(rs) sum[x]=sum[x]+sum[rs];
     53     }
     54     void rotate(int x)
     55     {
     56         int y=fa[x],z=fa[y],l=c[y][1]==x,r=l^1;
     57         if(!isroot(y)) c[z][c[z][1]==y]=x;
     58         if(c[x][r]) fa[c[x][r]]=y;
     59         fa[x]=z; fa[y]=x;
     60         c[y][l]=c[x][r]; c[x][r]=y;
     61         updata(y); updata(x);
     62     }
     63     void splay(int x)
     64     {
     65         while(!isroot(x))
     66         {
     67             int y=fa[x],z=fa[y];
     68             if(!isroot(y))
     69             {
     70                 if((c[z][0]==y)^(c[y][0]==x)) rotate(y);
     71                 else rotate(x);
     72             }
     73             rotate(x);
     74         }
     75     }
     76     void access(int x)
     77     {
     78         for(int p=0;x;p=x,x=fa[x])
     79         {
     80             splay(x); c[x][1]=p; if(p) fa[p]=x; updata(x);
     81         }
     82     }
     83     inline int findroot(int x)
     84     {
     85         access(x); splay(x);
     86         while(c[x][0]) x=c[x][0];
     87         return x;
     88     }
     89     void modify()
     90     {
     91         int x=read(),k=read(),p=read(),b=read();
     92         val[x].k=k; val[x].b=b;
     93         int t=findroot(x);
     94         if(t==x) sf[x]=0;
     95         else
     96         {
     97             access(x); splay(x);
     98             fa[c[x][0]]=0;c[x][0]=0;
     99             updata(x);
    100             if(findroot(sf[t])!=t)
    101             {
    102                 access(t); splay(t);
    103                 fa[t]=sf[t];
    104                 sf[t]=0;
    105             }
    106         }
    107         access(x); splay(x);
    108         if(findroot(p)==x)
    109             sf[x]=p;
    110         else fa[x]=p;
    111     }
    112     int query()
    113     {
    114         int x=read(),t=findroot(x);
    115         access(sf[t]); splay(sf[t]);
    116         int k=sum[sf[t]].k;
    117         int b=sum[sf[t]].b;
    118         //printf("%d %d
    ",k,b);
    119         if(k==1)
    120         {
    121             if(b==0) return -2;
    122             else return -1;
    123         }
    124         //printf("%d
    ",inv(k-1));
    125         int tmp=(-b+mod)*inv(k-1)%mod;
    126         //printf("%d
    ",tmp);
    127         access(x); splay(x);
    128         return sum[x].f(tmp);
    129     }
    130 }T;
    131 void dfs(int x)
    132 {
    133     vis[x]=tim;
    134     if(vis[fa[x]]==tim)
    135     {
    136         T.sf[x]=fa[x];
    137         return;
    138     }
    139     T.fa[x]=fa[x];
    140     if(!vis[T.fa[x]]) dfs(T.fa[x]);
    141 }
    142 int main()
    143 {
    144     //freopen("read.in","r",stdin);
    145     n=read();
    146     for(int i=1;i<=n;i++)
    147         T.val[i].k=read(),fa[i]=read(),T.val[i].b=read(),T.sum[i]=T.val[i];
    148     for(int i=1;i<=n;i++)
    149         if(!vis[i]) ++tim,dfs(i);
    150     m=read();
    151     //for(int i=1;i<=n;i++) printf("%d ",T.fa[i]); printf("
    ");
    152     //for(int i=1;i<=n;i++) printf("%d ",T.sf[i]); printf("
    ");
    153     while(m--)
    154     {
    155         char sd[4];
    156         scanf("%s",sd);
    157         if(sd[0]=='A') printf("%d
    ",T.query());
    158         if(sd[0]=='C') T.modify();
    159     }
    160     return 0;
    161 }
    View Code

    一道LCT好题 题如其名 真的是道好题 就可惜我不会做QAQ

    由于是一个基环树 对于一个环 可以把一条环边拆开 对于 这条边的起点 记录一个特殊的父亲

    那么 对于一个询问 先将环上的边exciting出来 然后在 拿来更新询问的点 所在的链 答案就可以出来了

     1 int query()
     2     {
     3         int x=read(),t=findroot(x);
     4         access(sf[t]); splay(sf[t]);
     5         int k=sum[sf[t]].k;
     6         int b=sum[sf[t]].b;
     7         //printf("%d %d
    ",k,b);
     8         if(k==1)
     9         {
    10             if(b==0) return -2;
    11             else return -1;
    12         }
    13         //printf("%d
    ",inv(k-1));
    14         int tmp=(-b+mod)*inv(k-1)%mod;
    15         //printf("%d
    ",tmp);
    16         access(x); splay(x);
    17         return sum[x].f(tmp);
    18     }

    ps: 维护答案的k 和 b 要注意ls rs 不要打反 holyshit 1hour+

  • 相关阅读:
    移动硬盘加密方法赏析
    Windows7下怎么对文件或者文件夹进行EFS加密
    win7怎么设置电脑自动关机
    电脑定时关机怎么设置
    用vb编程给u盘加密
    中医课件集合
    在手机上查询药品信息?PEP移动掌上药物信息参考
    【好站收藏】六脉医学资料下载网sixmed.cn
    百度进军C2C叫板淘宝电子商务领域竞争升级
    IBM 笔记本T43键盘帽安装手记
  • 原文地址:https://www.cnblogs.com/wcz112/p/6395211.html
Copyright © 2011-2022 走看看