bzoj 4754: [Jsoi2016]独特的树叶
Posted ws_ccd
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj 4754: [Jsoi2016]独特的树叶相关的知识,希望对你有一定的参考价值。
不得不说这是神题。
%%% http://blog.csdn.net/samjia2000/article/details/51762811
1 #include <cstdio> 2 #include <iostream> 3 #include <cstring> 4 #include <algorithm> 5 #include <set> 6 #define inf 0x3f3f3f3f 7 #define LL long long 8 #define eps 1e-8 9 #define N 100005 10 using namespace std; 11 inline int ra() 12 { 13 int x=0,f=1; char ch=getchar(); 14 while (ch<‘0‘ || ch>‘9‘) {if (ch==‘-‘) f=-1; ch=getchar();} 15 while (ch>=‘0‘ && ch<=‘9‘) {x=x*10+ch-‘0‘; ch=getchar();} 16 return x*f; 17 } 18 19 const int mod=1e+9+9; 20 const int prime=12589; 21 22 LL tim[N],q[N]; 23 int k; 24 struct node{int to,x; LL v;}u[N]; 25 bool cmp(node a, node b){return a.v<b.v;} 26 27 struct tree 28 { 29 int cnt,head[N]; 30 struct edge{int to,next;}e[N<<1]; 31 int n,r[N],fa[N],size[N]; 32 LL v[N],rt[N],f[N]; 33 LL suf[N],pre[N]; 34 35 void insert(int x, int y){e[++cnt].next=head[x]; e[cnt].to=y; head[x]=cnt;} 36 void init() 37 { 38 cnt=0; 39 for (int i=1; i<=n; i++) head[i]=r[i]=f[i]=fa[i]=rt[i]=0; 40 for (int i=1; i<n; i++) 41 { 42 int x=ra(),y=ra(); 43 insert(x,y); insert(y,x); 44 r[x]++; r[y]++; 45 } 46 } 47 48 void dfs1(int x) 49 { 50 size[x]=1; 51 for (int i=head[x];i;i=e[i].next) 52 { 53 if (e[i].to==fa[x]) continue; 54 fa[e[i].to]=x; 55 dfs1(e[i].to); 56 size[x]+=size[e[i].to]; 57 } 58 k=0; 59 for (int i=head[x];i;i=e[i].next) 60 if (fa[e[i].to]==x) q[++k]=v[e[i].to]; 61 sort(q+1,q+k+1); 62 v[x]=0; 63 for (int i=1; i<=k; i++) v[x]=(v[x]*prime%mod+q[i])%mod; 64 v[x]=(v[x]*prime%mod+size[x])%mod; 65 } 66 67 void dfs2(int x) 68 { 69 k=0; 70 if (x>1) u[++k].v=f[x],u[k].to=fa[x]; 71 for (int i=head[x];i;i=e[i].next) 72 if (fa[e[i].to]==x) 73 { 74 u[++k].to=e[i].to; 75 u[k].v=v[e[i].to]; 76 } 77 sort(u+1,u+1+k,cmp); 78 for (int i=1; i<=k; i++) pre[i]=(pre[i-1]*prime%mod+u[i].v)%mod; 79 suf[k+1]=0; 80 for (int i=k; i>=1; i--) suf[i]=(suf[i+1]+u[i].v*tim[k-i]%mod)%mod; 81 for (int i=1; i<=k; i++) 82 if (u[i].to!=fa[x]) 83 { 84 f[u[i].to]=(pre[i-1]*tim[k-i]%mod+suf[i+1])%mod; 85 f[u[i].to]=(f[u[i].to]*prime%mod+n-size[u[i].to])%mod; 86 } 87 for (int i=head[x];i;i=e[i].next) 88 if (fa[e[i].to]==x) dfs2(e[i].to); 89 } 90 void cal() 91 { 92 dfs1(1); dfs2(1); 93 for (int x=1; x<=n; x++) 94 { 95 k=0; 96 for (int i=head[x];i;i=e[i].next) 97 if (fa[e[i].to]==x) q[++k]=v[e[i].to]; 98 if (fa[x]) q[++k]=f[x]; 99 sort(q+1,q+k+1); 100 rt[x]=0; 101 for (int i=1; i<=k; i++) rt[x]=(rt[x]*prime%mod+q[i])%mod; 102 rt[x]=(rt[x]*prime%mod+n)%mod; 103 } 104 } 105 }a,b; 106 107 int m; 108 set<LL> s; 109 110 int main(int argc, char const *argv[]) 111 { 112 tim[0]=1; s.clear(); 113 m=ra(); 114 for (int i=1; i<=m+2; i++) tim[i]=tim[i-1]*prime%mod; 115 a.n=m; a.init(); b.n=m+1; b.init(); a.cal(); b.cal(); 116 for (int i=1; i<=m; i++) s.insert(a.rt[i]); 117 for (int i=1; i<=m+1; i++) 118 if (b.r[i]==1 && ((i!=1 && s.find(b.f[i])!=s.end()) || (i==1 && s.find(b.v[b.e[b.head[i]].to])!=s.end()))) 119 { 120 printf("%d\n",i); return 0; 121 } 122 return 0; 123 }
以上是关于bzoj 4754: [Jsoi2016]独特的树叶的主要内容,如果未能解决你的问题,请参考以下文章