【ZJOJ 5454】【NOIP2017提高A组冲刺11.5】仔细的检查
来源:互联网 发布:福建广播网络电视台 编辑:程序博客网 时间:2024/05/29 19:20
Description
nodgd家里种了一棵树,有一天nodgd比较无聊,就把这棵树画在了一张纸上。另一天nodgd更无聊,就又画了一张。
这时nodgd发现,两次画的顺序是不一样的,这就导致了原本的某一个节点u0在第一幅图中编号为u1,在第二副图中编号为u2。
于是,nodgd决定检查一下他画出的两棵树到底是不是一样的。nodgd已经给每棵树的节点都从1到n进行了编号,即每棵树有n个节点。
如果存在一个1到n的排列p1p2…pn,对于第一幅图中的任意一条边(u,v),在第二幅图中都能找到一条边(pu,pv),则认为这两幅图中的树是一样的。
Solution
树的哈希版子题, (写得越猎奇越好)
Code
#include <cstdio>#include <algorithm>#define fo(i,a,b) for(int i=a;i<=b;i++)#define fod(i,a,b) for(int i=a;i>=b;i--)#define efo(i,q) for(int i=A[E][q];i;i=B[E][i][0])using namespace std;typedef long long LL;typedef LL Uin;const int N=200500;const Uin h2mo=1010003;//23 67const Uin h1mo=4988741;//23 67int read(int &n){ char ch=' ';int q=0,w=1; for(;(ch!='-')&&((ch<'0')||(ch>'9'));ch=getchar()); if(ch=='-')w=-1,ch=getchar(); for(;ch>='0' && ch<='9';ch=getchar())q=q*10+ch-48;n=q*w;return n;}int n,m,ans;int B[4][2*N][2],A[4][N],B0[4],bv[4][N];int Si1[N],Sz;Uin Si[2][N];int d[2][N];int en;int Ans[N],As[N];struct qqww{ Uin h1,h2; Uin sh1,sh2; Uin z1,z2; int i,k;}p[2][N],p1[N],p2[N];void link(int I,int q,int w){ bv[I][q]++;bv[I][w]++; B[I][++B0[I]][0]=A[I][q],A[I][q]=B0[I],B[I][B0[I]][1]=w; if(I<2)B[I][++B0[I]][0]=A[I][w],A[I][w]=B0[I],B[I][B0[I]][1]=q;}int FDz(int E,int q,int fa){ Si1[q]=1; int mx=0; efo(i,q)if(B[E][i][1]!=fa)Si1[q]+=FDz(E,B[E][i][1],q),mx=max(mx,Si1[B[E][i][1]]); mx=max(mx,n-Si1[q]); if(mx<Sz) { Sz=mx; d[E][d[E][0]=1]=q; }else if(mx==Sz)d[E][++d[E][0]]=q; return Si1[q];}int dffffff(int E,int q,int fa){ Si[E][q]=1; int mx=0; efo(i,q)if(B[E][i][1]!=fa)Si[E][q]+=dffffff(E,B[E][i][1],q); return Si[E][q];}Uin er1[N],er2[N];Uin H1,H2;void dfsf(int E,int q,int fa,int c){ Uin cl=bv[E][q]-(fa!=0); cl=Si[E][q]*Si[E][q]*Si[E][q]*23333LL; p[E][q].i=q;p[E][q].k=E; p[E][q].sh1=p[E][q].h1=er1[c]*(Si[E][q]*Si[E][q]%h1mo*Si[E][q]*23333LL%h1mo-bv[E][q]*bv[E][q]%h1mo)%h1mo; p[E][q].sh2=p[E][q].h2=er2[c]*(Si[E][q]*Si[E][q]%h2mo*Si[E][q]*23333LL%h2mo-bv[E][q]*bv[E][q]%h2mo)%h2mo; efo(i,q)if(B[E][i][1]!=fa) { dfsf(E,B[E][i][1],q,c+1); p[E][q].sh1+=p[E][B[E][i][1]].sh1; p[E][q].sh2+=p[E][B[E][i][1]].sh2; if(p[E][q].sh2>=h2mo)p[E][q].sh2-=h2mo; if(p[E][q].sh1>=h1mo)p[E][q].sh1-=h1mo; }}void dfs(int E,int q,int fa,Uin h1,Uin h2){ h2=(h2%h2mo+h2mo)%h2mo; h1=(h1%h1mo+h1mo)%h1mo; p[E][q].z1=((LL)p[E][q].h1+(LL)41LL*p[E][q].sh1%h1mo+(LL)h1*443ll%h1mo+111LL*p[E][fa].z1)%h1mo; p[E][q].z2=((LL)p[E][q].h2+(LL)87*p[E][q].sh2%h2mo+(LL)h2*47%h2mo+(LL)13143LL*p[E][fa].z2)%h2mo; H1=(H1+p[E][q].z1)%h1mo; H2=(H2+p[E][q].z2)%h2mo; h1=(h1+p[E][q].sh1)%h1mo; h2=(h2+p[E][q].sh2)%h2mo; efo(i,q)if(B[E][i][1]!=fa) dfs(E,B[E][i][1],q,h1-p[E][B[E][i][1]].sh1,h2-p[E][B[E][i][1]].sh2);}bool OK;bool PX(qqww q,qqww w){return q.z1<w.z1||(q.z1==w.z1&&q.z2<w.z2);}void dfsS(int q,int w,int fa){ if(!OK)return; if(p[0][q].z1!=p[1][w].z1||p[0][q].z2!=p[1][w].z2){OK=0;return;} Ans[q]=w; int E=0; int t1=0; efo(i,q)p1[++t1]=p[0][B[0][i][1]]; sort(p1+1,p1+1+t1,PX); E=1; int t2=0; efo(i,w)p2[++t2]=p[1][B[1][i][1]]; sort(p2+1,p2+1+t2,PX); if(t1!=t2){OK=0;return;} fod(i,t1,1)link(2,q,p1[i].i); fod(i,t1,1)link(3,w,p2[i].i); for(int i=A[2][q],j=A[3][w];i;i=B[2][i][0],j=B[3][j][0])if(!Ans[B[2][i][1]])dfsS(B[2][i][1],B[3][j][1],q);}int main(){ freopen("check.in","r",stdin); freopen("check.out","w",stdout); int q,w; read(n); er1[1]=23;fo(i,2,n)er1[i]=(er1[i-1]*23LL)%h1mo; er2[1]=67;fo(i,2,n)er2[i]=(er2[i-1]*67LL)%h2mo; fo(i,1,n-1)read(q),read(w),link(0,q,w); fo(i,1,n-1)read(q),read(w),link(1,q,w); Sz=1e9; FDz(0,1,0); Sz=1e9; FDz(1,1,0); OK=0; fo(I,1,d[0][0])fo(J,1,d[1][0])if(bv[0][d[0][I]]==bv[1][d[1][J]]) { q=d[0][I];w=d[1][J]; dffffff(0,q,0);dffffff(1,w,0); dfsf(0,q,0,1); H1=H2=0;dfs(0,q,0,0,0); Uin q1=H1,q2=H2; dfsf(1,w,0,1); H1=H2=0;dfs(1,w,0,0,0); if(q1!=H1||q2!=H2)continue; OK=1; dfsS(q,w,0); if(OK)break; } if(!OK){printf("NO\n");return 0;} printf("YES\n"); fo(i,1,n)printf("%d ",Ans[i]); return 0;}
阅读全文
0 0
- 【ZJOJ 5454】【NOIP2017提高A组冲刺11.5】仔细的检查
- Jzoj5454【NOIP2017提高A组冲刺11.5】仔细的检查
- JZOJ5454. 【NOIP2017提高A组冲刺11.5】仔细的检查
- JZOJ5454. 【NOIP2017提高A组冲刺11.5】仔细的检查 树hash
- JZOJ 5454. 【NOIP2017提高A组冲刺11.5】仔细的检查
- 【NOIP2017提高组】仔细的检查
- 【NOIP2017提高A组冲刺11.5】轰炸
- 【NOIP2017提高A组冲刺11.5】总结
- [JZOJ5456]【NOIP2017提高A组冲刺11.6】奇怪的队列
- Jzoj5456【NOIP2017提高A组冲刺11.6】奇怪的队列
- JZOJ5456. 【NOIP2017提高A组冲刺11.6】奇怪的队列
- 【JZOJ 5452】【NOIP2017提高A组冲刺11.5】轰炸
- JZOJ 5452. 【NOIP2017提高A组冲刺11.5】轰炸
- JZOJ 5453. 【NOIP2017提高A组冲刺11.5】好路线
- Jzoj5453【NOIP2017提高A组冲刺11.5】好路线
- JZOJ5453. 【NOIP2017提高A组冲刺11.5】好路线
- Jzoj5452【NOIP2017提高A组冲刺11.5】轰炸
- JZOJ5452. 【NOIP2017提高A组冲刺11.5】轰炸
- varnish 基础应用
- mysql分库分表在什么时候用?如何用?
- 安卓扫描车牌识别的功能SDK
- 【软考】-防火墙
- Distances to Zero
- 【ZJOJ 5454】【NOIP2017提高A组冲刺11.5】仔细的检查
- 并发编程(11)-Future模式
- java基础之线程(重点)
- 生成波动图
- java se--2.数组-2.一维数组
- 训练日记
- Java字符串的操作
- 网络七层
- 一个获取鼠标位置和键盘按钮的图形化界面一个 工程文件