题意:
很简单的英文自己看,要是这么简单都看不懂以后怎么办?
废话:
感觉我这个人就十分不适合写lct
今天一个傻逼错误调了一下午。。
昨天的lct比别人慢了10倍。。
今天的lct调到死后WA了。。
静态查错+对拍一辈子没弄出来
我的不靠谱对拍。。(极限生成慢,但大数据还是没问题)
#include<cstdio>
#include<cstdlib>
#include<ctime>
#include<cstring>
using namespace std;
typedef long long LL;
const int N=100005;
int n,m;
struct qq
{
int x,y;
}s[N];
int f[N];
int find (int x)
{
return f[x]==x?f[x]:f[x]=find(f[x]);
}
int main()
{
printf("3\n");
for (int TT=1;TT<=3;TT++)
{
srand(time(0));
n=100;m=100;
printf("%d %d\n",n,m);
for (int u=1;u<=n;u++) printf("%d ",rand()%10+1);
printf("\n");
for (int u=1;u<=n;u++) f[u]=u;
for (int u=1;u<n;u++)
{
int x=rand()%n+1,y=rand()%n+1;
if (find(x)==find(y)) {u--;continue;}
s[u].x=x;s[u].y=y;
printf("%d %d\n",x,y);
f[find(x)]=find(y);
}
for (int u=1;u<=m;u++)
{
int op=rand()%4+1;
printf("%d ",op);
if (op==1)
{
int t=rand()%(n-1)+1;
printf("%d %d ",s[t].x,s[t].y);
for (int u=1;u<=n;u++) f[u]=u;
for (int u=1;u<n;u++)
{
if (u==t) continue;
int fx=find(s[u].x),fy=find(s[u].y);
f[fx]=fy;
}
while (true)
{
int x=rand()%n+1,y=rand()%n+1;
if (find(x)==find(y)) continue;
s[t].x=x;s[t].y=y;
break;
}
printf("%d %d\n",s[t].x,s[t].y);
}
if (op==2||op==3)
printf("%d %d %d\n",rand()%n+1,rand()%n+1,rand()%10+1);
if (op==4)
printf("%d %d\n",rand()%n+1,rand()%n+1);
}
}
return 0;
}`#include<cstdio>
#include<cstring>
#include<stack>
#include<iostream>
using namespace std;
const int MAX=1<<30;
const int N=100005;
int T;
int n,m;
struct qq
{
int son[2],fa;
bool rev;
int mx1,mx2;//最大值 次大值
int num1,num2;//个数
int lalal;//是否全部变成了某个数 -1:没有
int add;//add的中文:加
int tot;//人数
int d;//这个点的值
void bt (int x)
{
d=x;
son[0]=son[1]=fa=rev=0;
mx1=x;num1=1;
mx2=-MAX;num2=0;
lalal=-1;
add=0;tot=1;
};
}s[N];
void solve (int x,int c,int tot)//我要更新的节点
{
if (tot==0) return ;
if (s[x].mx1<c)
{
s[x].mx2=s[x].mx1;/********/
s[x].num2=s[x].num1;/********/
s[x].mx1=c;
s[x].num1=tot;
}
else if (s[x].mx1==c) s[x].num1+=tot;
else if (s[x].mx2<c) {s[x].mx2=c;s[x].num2=tot;}
else if (s[x].mx2==c) s[x].num2+=tot;
}
void update (int x)
{
int s1=s[x].son[0],s2=s[x].son[1];
s[x].tot=s[s1].tot+s[s2].tot+1;
/*更新最大次大值以及他们的个数*/
s[x].mx1=s[x].d;s[x].num1=1;
s[x].mx2=-MAX;s[x].num2=0;
if (s1!=0) solve(x,s[s1].mx1,s[s1].num1),solve(x,s[s1].mx2,s[s1].num2);
if (s2!=0) solve(x,s[s2].mx1,s[s2].num1),solve(x,s[s2].mx2,s[s2].num2);
/*更新最大次大值以及他们的个数*/
}
void change (int x,int c)//全部变成了c
{
if (x==0) return ;
s[x].lalal=c;s[x].d=c;s[x].add=0;
s[x].mx1=c;s[x].num1=s[x].tot;
s[x].mx2=-MAX;s[x].num2=0;
}
void ADD (int x,int c)
{
if (x==0) return ;
s[x].d+=c;
s[x].add+=c;
s[x].mx1+=c;
if (s[x].mx2!=-MAX) s[x].mx2+=c;
}
void Push_down(int x)
{
if (x==0) return ;
int s1=s[x].son[0],s2=s[x].son[1];
if (s[x].lalal!=-1)
{
change(s1,s[x].lalal);change(s2,s[x].lalal);
s[x].lalal=-1;
}
if (s[x].add!=0)
{
int Add=s[x].add;s[x].add=0;
ADD(s1,Add);ADD(s2,Add);
}
if (s[x].rev)
{
s[x].rev=false;
s[s1].rev^=1;s[s2].rev^=1;
swap(s[x].son[0],s[x].son[1]);
}
}
bool Is_root(int x)
{
if((s[s[x].fa].son[0]!=x)&&(s[s[x].fa].son[1]!=x)) return true;
return false;
}
void rotate (int x)
{
int y=s[x].fa,z=s[y].fa;
int a=s[y].son[1]==x,b=s[z].son[1]==y;
int g=s[x].son[a^1];
if (!Is_root(y)) s[z].son[b]=x;s[x].fa=z;
s[x].son[a^1]=y; s[y].fa=x;
s[y].son[a]=g; if (g!=0) s[g].fa=y;
update(y);update(x);
}
stack<int> S;
void Preserve(int x)
{
int top=0;
while(!Is_root(x)) S.push(x),x=s[x].fa;S.push(x);
while(!S.empty()) Push_down(S.top()),S.pop();
}
void Splay (int x)
{
Preserve(x);
while (!Is_root(x))
{
int y=s[x].fa,z=s[y].fa;
if (Is_root(y)) rotate(x);
else
{
if ((s[y].son[1]==x)==(s[z].son[1]==y)) rotate(y);
else rotate(x);
rotate(x);
}
}
/*printf("\n");
for (int u=1;u<=3;u++)
printf("%d d:%d fa:%d mx1:%d num1:%d tot:%d s1:%d s2:%d\n",u,s[u].d,s[u].fa,s[u].mx1,s[u].num1,s[u].tot,s[u].son[0],s[u].son[1]);
printf("%d\n",x);
printf("\n");*/
// update(x);
/* for (int u=1;u<=3;u++)
printf("%d d:%d fa:%d mx1:%d num1:%d tot:%d s1:%d s2:%d\n",u,s[u].d,s[u].fa,s[u].mx1,s[u].num1,s[u].tot,s[u].son[0],s[u].son[1]);*/
}
void Access (int x)
{
int last=0;
while (x!=0)
{
Splay(x);
s[x].son[1]=last;
update(x);
last=x;
x=s[x].fa;
}
}
void Make_root (int x)
{
Access(x);
Splay(x);
s[x].rev^=1;
}
void Link (int x,int y)
{
Make_root(x);
s[x].fa=y;
}
void Split (int x,int y)
{
Make_root(x);
/*for (int u=1;u<=3;u++)
printf("%d d:%d fa:%d mx1:%d num1:%d mx2:%d num2:%d tot:%d s1:%d s2:%d\n",u,s[u].d,s[u].fa,s[u].mx1,s[u].num1,s[u].mx2,s[u].num2,s[u].tot,s[u].son[0],s[u].son[1]);*/
Access(y);
/*printf("\nYES\n");
for (int u=1;u<=3;u++)
printf("%d d:%d fa:%d mx1:%d num1:%d mx2:%d num2:%d tot:%d s1:%d s2:%d\n",u,s[u].d,s[u].fa,s[u].mx1,s[u].num1,s[u].mx2,s[u].num2,s[u].tot,s[u].son[0],s[u].son[1]);*/
Splay(y);
}
void Cut (int x,int y)
{
Split(x,y);
s[x].fa=0;s[y].son[0]=0;/*******/
update(y);
/*printf("%d %d\n",x,y);
for (int u=1;u<=n;u++)
printf("%d fa:%d s1:%d s2:%d\n",u,s[u].fa,s[u].son[0],s[u].son[1]);*/
}
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int main()
{
T=read();
for (int fyc=1;fyc<=T;fyc++)
{
printf("Case #%d:\n",fyc);
n=read();m=read();
for (int u=1;u<=n;u++)
s[u].bt(read());
for (int u=1;u<n;u++)
{
int x=read(),y=read();
Link(x,y);
}
for (int u=1;u<=m;u++)
{
int op=read();
if (op==1)//link和cut
{
int x,y;
x=read();y=read();Cut(x,y);
x=read();y=read();Link(x,y);
}
if (op==2)//将x->y这条路径都变成c
{
int x,y,c;
x=read();y=read();c=read();
Split(x,y);
change(y,c);
}
if (op==3)
{
int x,y,c;
x=read();y=read();c=read();
Split(x,y);
ADD(y,c);
}
if (op==4)
{
int x,y;
x=read();y=read();
Split(x,y);
//printf("%d %d %d %d\n",s[y].mx1,s[y].num1,s[y].mx2,s[y].num2);
if (s[y].num2==0) printf("ALL SAME\n");
else printf("%d %d\n",s[y].mx2,s[y].num2);
}
/*for (int u=1;u<=n;u++)
printf("%d fa:%d s1:%d s2:%d\n",u,s[u].fa,s[u].son[0],s[u].son[1]);*/
}
}
return 0;
}`
题解
不知道我有没有资格写题解,应该还是有的吧。。
就是一个裸的LCT
维护一堆值,具体看代码,要说的太多。。
全部变量在代码都有注释的,这个可以放心,觉得看得懂。。
然后部分语句也有注释。。
要是有哪一个dalao赏脸拿去对拍,非常欢迎啊
要是发现我WA的数据可以给我,十分欢迎。。
我实在是拍不出了
代码
#include<cstdio>
#include<cstring>
#include<stack>
#include<iostream>
using namespace std;
const int MAX=1<<30;
const int N=100005;
int T;
int n,m;
struct qq
{
int son[2],fa;
bool rev;
int mx1,mx2;//最大值 次大值
int num1,num2;//个数
int lalal;//是否全部变成了某个数 -1:没有
int add;//add的中文:加
int tot;//人数
int d;//这个点的值
void bt (int x)
{
d=x;
son[0]=son[1]=fa=rev=0;
mx1=x;num1=1;
mx2=-MAX;num2=0;
lalal=-1;
add=0;tot=1;
};
}s[N];
void solve (int x,int c,int tot)//我要更新的节点
{
if (tot==0) return ;
if (s[x].mx1<c)
{
s[x].mx2=s[x].mx1;/********/
s[x].num2=s[x].num1;/********/
s[x].mx1=c;
s[x].num1=tot;
}
else if (s[x].mx1==c) s[x].num1+=tot;
else if (s[x].mx2<c) {s[x].mx2=c;s[x].num2=tot;}
else if (s[x].mx2==c) s[x].num2+=tot;
}
void update (int x)
{
int s1=s[x].son[0],s2=s[x].son[1];
s[x].tot=s[s1].tot+s[s2].tot+1;
/*更新最大次大值以及他们的个数*/
s[x].mx1=s[x].d;s[x].num1=1;
s[x].mx2=-MAX;s[x].num2=0;
if (s1!=0) solve(x,s[s1].mx1,s[s1].num1),solve(x,s[s1].mx2,s[s1].num2);
if (s2!=0) solve(x,s[s2].mx1,s[s2].num1),solve(x,s[s2].mx2,s[s2].num2);
/*更新最大次大值以及他们的个数*/
}
void change (int x,int c)//全部变成了c
{
if (x==0) return ;
s[x].lalal=c;s[x].d=c;s[x].add=0;
s[x].mx1=c;s[x].num1=s[x].tot;
s[x].mx2=-MAX;s[x].num2=0;
}
void ADD (int x,int c)
{
if (x==0) return ;
s[x].d+=c;
s[x].add+=c;
s[x].mx1+=c;
if (s[x].mx2!=-MAX) s[x].mx2+=c;
}
void Push_down(int x)
{
if (x==0) return ;
int s1=s[x].son[0],s2=s[x].son[1];
if (s[x].lalal!=-1)
{
change(s1,s[x].lalal);change(s2,s[x].lalal);
s[x].lalal=-1;
}
if (s[x].add!=0)
{
int Add=s[x].add;s[x].add=0;
ADD(s1,Add);ADD(s2,Add);
}
if (s[x].rev)
{
s[x].rev=false;
s[s1].rev^=1;s[s2].rev^=1;
swap(s[x].son[0],s[x].son[1]);
}
}
bool Is_root(int x)
{
if((s[s[x].fa].son[0]!=x)&&(s[s[x].fa].son[1]!=x)) return true;
return false;
}
void rotate (int x)
{
int y=s[x].fa,z=s[y].fa;
int a=s[y].son[1]==x,b=s[z].son[1]==y;
int g=s[x].son[a^1];
if (!Is_root(y)) s[z].son[b]=x;s[x].fa=z;
s[x].son[a^1]=y; s[y].fa=x;
s[y].son[a]=g; if (g!=0) s[g].fa=y;
update(y);update(x);
}
stack<int> S;
void Preserve(int x)
{
int top=0;
while(!Is_root(x)) S.push(x),x=s[x].fa;S.push(x);
while(!S.empty()) Push_down(S.top()),S.pop();
}
void Splay (int x)
{
Preserve(x);
while (!Is_root(x))
{
int y=s[x].fa,z=s[y].fa;
if (Is_root(y)) rotate(x);
else
{
if ((s[y].son[1]==x)==(s[z].son[1]==y)) rotate(y);
else rotate(x);
rotate(x);
}
}
/*printf("\n");
for (int u=1;u<=3;u++)
printf("%d d:%d fa:%d mx1:%d num1:%d tot:%d s1:%d s2:%d\n",u,s[u].d,s[u].fa,s[u].mx1,s[u].num1,s[u].tot,s[u].son[0],s[u].son[1]);
printf("%d\n",x);
printf("\n");*/
// update(x);
/* for (int u=1;u<=3;u++)
printf("%d d:%d fa:%d mx1:%d num1:%d tot:%d s1:%d s2:%d\n",u,s[u].d,s[u].fa,s[u].mx1,s[u].num1,s[u].tot,s[u].son[0],s[u].son[1]);*/
}
void Access (int x)
{
int last=0;
while (x!=0)
{
Splay(x);
s[x].son[1]=last;
update(x);
last=x;
x=s[x].fa;
}
}
void Make_root (int x)
{
Access(x);
Splay(x);
s[x].rev^=1;
}
void Link (int x,int y)
{
Make_root(x);
s[x].fa=y;
}
void Split (int x,int y)
{
Make_root(x);
/*for (int u=1;u<=3;u++)
printf("%d d:%d fa:%d mx1:%d num1:%d mx2:%d num2:%d tot:%d s1:%d s2:%d\n",u,s[u].d,s[u].fa,s[u].mx1,s[u].num1,s[u].mx2,s[u].num2,s[u].tot,s[u].son[0],s[u].son[1]);*/
Access(y);
/*printf("\nYES\n");
for (int u=1;u<=3;u++)
printf("%d d:%d fa:%d mx1:%d num1:%d mx2:%d num2:%d tot:%d s1:%d s2:%d\n",u,s[u].d,s[u].fa,s[u].mx1,s[u].num1,s[u].mx2,s[u].num2,s[u].tot,s[u].son[0],s[u].son[1]);*/
Splay(y);
}
void Cut (int x,int y)
{
Split(x,y);
s[x].fa=0;s[y].son[0]=0;/*******/
update(y);
/*printf("%d %d\n",x,y);
for (int u=1;u<=n;u++)
printf("%d fa:%d s1:%d s2:%d\n",u,s[u].fa,s[u].son[0],s[u].son[1]);*/
}
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int main()
{
T=read();
for (int fyc=1;fyc<=T;fyc++)
{
printf("Case #%d:\n",fyc);
n=read();m=read();
for (int u=1;u<=n;u++)
s[u].bt(read());
for (int u=1;u<n;u++)
{
int x=read(),y=read();
Link(x,y);
}
for (int u=1;u<=m;u++)
{
int op=read();
if (op==1)//link和cut
{
int x,y;
x=read();y=read();Cut(x,y);
x=read();y=read();Link(x,y);
}
if (op==2)//将x->y这条路径都变成c
{
int x,y,c;
x=read();y=read();c=read();
Split(x,y);
change(y,c);
}
if (op==3)
{
int x,y,c;
x=read();y=read();c=read();
Split(x,y);
ADD(y,c);
}
if (op==4)
{
int x,y;
x=read();y=read();
Split(x,y);
//printf("%d %d %d %d\n",s[y].mx1,s[y].num1,s[y].mx2,s[y].num2);
if (s[y].num2==0) printf("ALL SAME\n");
else printf("%d %d\n",s[y].mx2,s[y].num2);
}
/*for (int u=1;u<=n;u++)
printf("%d fa:%d s1:%d s2:%d\n",u,s[u].fa,s[u].son[0],s[u].son[1]);*/
}
}
return 0;
}