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\n",T.query(u,v));
111             else printf("impossible\n");
112         }
113         if(sd[0]=='b')
114         {
115             if(T.find(u)==T.find(v))
116                 printf("no\n");
117             else T.link(u,v),printf("yes\n");
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\n");
151             else printf("no\n");
152         }
153         else if(Q[i].dps==1)
154         {
155             if(Q[i].tp==1) printf("impossible\n");
156             else printf("%d\n",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\n",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\n");
179         else printf("Yes\n");
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\n",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\n");
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",N);printf("%d\n",M);
11     for(int i=1;i<=N;i++) printf("%d ",rand()*rand()%1000000); printf("\n");
12     for(int i=2;i<=N;i++)
13     {
14         int x=rand()%(i-1)+1;
15         printf("%d %d\n",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\n",rand()%N+1,rand()%N+1);
22         if(tx==3) printf("%d %d %d\n",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\n",mi[y]);
111         if(tp==2) printf("%lld\n",mx[y]);
112         if(tp==3) printf("%lld\n",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\n",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.\n"); continue;}
133             if(g==kg){printf("Success.\n"); continue;}
134             if(colnum[x][kg]>=2||colnum[y][kg]>=2)
135             {
136                 printf("Error 1.\n"); continue;
137             }
138             if(T[kg].find(x)==T[kg].find(y))
139             {
140                 printf("Error 2.\n"); continue;
141             }
142             printf("Success.\n");
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\n");
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\n",k,b);
119         if(k==1)
120         {
121             if(b==0) return -2;
122             else return -1;
123         }
124         //printf("%d\n",inv(k-1));
125         int tmp=(-b+mod)*inv(k-1)%mod;
126         //printf("%d\n",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("\n");
152     //for(int i=1;i<=n;i++) printf("%d ",T.sf[i]); printf("\n");
153     while(m--)
154     {
155         char sd[4];
156         scanf("%s",sd);
157         if(sd[0]=='A') printf("%d\n",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\n",k,b);
 8         if(k==1)
 9         {
10             if(b==0) return -2;
11             else return -1;
12         }
13         //printf("%d\n",inv(k-1));
14         int tmp=(-b+mod)*inv(k-1)%mod;
15         //printf("%d\n",tmp);
16         access(x); splay(x);
17         return sum[x].f(tmp);
18     }

 

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

 

posted @ 2017-02-13 20:13  蛤鸡  阅读(225)  评论(0编辑  收藏  举报