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 }

 

posted @ 2017-04-01 22:01  ws_ccd  阅读(563)  评论(0编辑  收藏  举报