Tree hdu5002
来源:互联网 发布:淘宝送手机充值卡 编辑:程序博客网 时间:2024/06/10 23:01
题意:
很简单的英文自己看,要是这么简单都看不懂以后怎么办?
废话:
感觉我这个人就十分不适合写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;}
阅读全文
0 0
- Tree hdu5002
- HDU5002--Tree(LCT)
- LCT - hdu5002 Tree
- hdu5002:Tree (LCT)
- hdu5002
- hdu5002 LCT
- 【动态树X脑残错误】hdu5002
- 2014鞍山网络预选赛1006(LCT模板题)hdu5002
- Tree
- tree
- tree
- TREE
- Tree
- Tree
- tree
- tree
- tree
- tree
- docker 官网 出现技术故障
- 【服务器】服务器上设置定时任务,定时执行Java程序
- JS中的计算其中的一些对应的长度
- get和post的区别
- 卡塔兰数及模板
- Tree hdu5002
- Java实现Morris遍历二叉树
- MVC中使用ActionFilterAttribute全局过滤器出现:网页无法正常运作 将您重定向的次数过多。解决办法
- redis 初识
- npm安装vue
- DHCP其他
- mybatis打印sql日志
- 无坑畅玩minikube(利用阿里云镜像编译minikube)
- UNIX/Linux中的文件描述符 && 为何删除DB2的容器之后表空间仍然可以访问