码迷,mamicode.com
首页 > 其他好文 > 详细

A1486. 树(王康宁)

时间:2015-03-19 23:31:29      阅读:249      评论:0      收藏:0      [点我收藏+]

标签:

题目:http://www.tsinsen.com/A1486

题解:

        其实看到和路径有关的就应该想到点分治。

        我们找出重心之后遍历每一棵子树得到它的 { x=经过特殊点的个数,y=到rt的异或和}

        然后我们按x排序,维护两个头尾指针不断把满足条件的加入trie,然后把左边的放进trie里查询。

        但是还有一个问题,所取的两个点不能位于同一棵子树!!!

        我yy了一个做法。我们在用三元组来记录{ x=经过特殊点的个数,y=到rt的异或和,ch=所属子树}

        然后往trie里插的时候,每条边保留两个ch表示有哪个子树的点从trie往下经过了这里。必须保证这两个ch不同。

        然后查询的时候就判断就行了。注意任何时刻往下走的时候都要判断可行性,否则直接返回-1.

代码:

技术分享
  1 #include<cstdio>
  2 #include<cstdlib>
  3 #include<cmath>
  4 #include<cstring>
  5 #include<algorithm>
  6 #include<iostream>
  7 #include<vector>
  8 #include<map>
  9 #include<set>
 10 #include<queue>
 11 #include<string>
 12 #define inf 1000000000
 13 #define maxn 250000+5
 14 #define maxm 8000000+5
 15 #define eps 1e-10
 16 #define ll long long
 17 #define ull unsigned long long
 18 #define pa pair<int,int>
 19 #define for0(i,n) for(int i=0;i<=(n);i++)
 20 #define for1(i,n) for(int i=1;i<=(n);i++)
 21 #define for2(i,x,y) for(int i=(x);i<=(y);i++)
 22 #define for3(i,x,y) for(int i=(x);i>=(y);i--)
 23 #define for4(i,x) for(int i=head[x],y=e[i].go;i;i=e[i].next,y=e[i].go)
 24 #define for5(n,m) for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)
 25 #define mod 1000000007
 26 #define lch k<<1,l,mid
 27 #define rch k<<1|1,mid+1,r
 28 #define sqr(x) (x)*(x)
 29 using namespace std;
 30 inline int read()
 31 {
 32     int x=0,f=1;char ch=getchar();
 33     while(ch<0||ch>9){if(ch==-)f=-1;ch=getchar();}
 34     while(ch>=0&&ch<=9){x=10*x+ch-0;ch=getchar();}
 35     return x*f;
 36 }
 37 int n,m,k,cnt,tot,head[maxn],v[maxn],w[maxn],t[maxm][2][3],s[maxn],f[maxn],sum,rt,ans=-1;
 38 bool del[maxn];
 39 struct edge{int go,next;}e[2*maxn];
 40 struct rec{int x,y,ch;}a[maxn];
 41 inline bool cmp(rec a,rec b){return a.x<b.x;}
 42 inline void add(int x,int y)
 43 {
 44     e[++tot]=(edge){y,head[x]};head[x]=tot;
 45     e[++tot]=(edge){x,head[y]};head[y]=tot;
 46 }
 47 inline void insert(int y,int ch)
 48 {
 49     int x=0;
 50     for3(i,30,0)
 51     {
 52         int j=y>>i&1;
 53         if(!t[x][j][0])t[x][j][0]=++tot,t[x][j][1]=ch;
 54         else if(t[x][j][1]!=ch)t[x][j][2]=ch;
 55         x=t[x][j][0];
 56     }
 57 }
 58 inline int query(int y,int ch)
 59 {
 60     int x=0,ret=0;
 61     for3(i,30,0)
 62     {
 63         int j=y>>i&1^1;
 64         if(t[x][j][0]&&((t[x][j][1]&&t[x][j][1]!=ch)||(t[x][j][2]&&t[x][j][2]!=ch)))ret^=1<<i,x=t[x][j][0];
 65         else 
 66         {
 67             j^=1;
 68             if(t[x][j][0]&&((t[x][j][1]&&t[x][j][1]!=ch)||(t[x][j][2]&&t[x][j][2]!=ch)))x=t[x][j][0];
 69             else return -1;
 70         }
 71     }
 72     return ret;
 73 }   
 74 inline void getdep(int x,int fa,int w1,int w2,int w3)
 75 {
 76     a[++cnt]=(rec){w1,w2,w3};
 77     for4(i,x)if(!del[y]&&y!=fa)getdep(y,x,w1+v[y],w2^w[y],w3);
 78 }
 79 inline void getrt(int x,int fa)
 80 {
 81     s[x]=1;f[x]=0;
 82     for4(i,x)if(!del[y]&&y!=fa)
 83     {
 84         getrt(y,x);
 85         s[x]+=s[y];
 86         f[x]=max(f[x],s[y]);
 87     }
 88     f[x]=max(f[x],sum-s[x]);
 89     if(f[x]<f[rt])rt=x;
 90 }
 91 inline void work(int x)
 92 {
 93     del[x]=1;cnt=0;
 94     for4(i,x)if(!del[y])getdep(y,x,v[x]+v[y],w[x]^w[y],y);
 95     sort(a+1,a+cnt+1,cmp);
 96     int tmp=k+v[x],j=cnt;
 97     for1(i,cnt)
 98     {
 99         while(j>i&&a[i].x+a[j].x>=tmp)insert(a[j].y,a[j].ch),j--;
100         ans=max(ans,query(a[i].y^w[x],a[i].ch));
101     }
102     for1(i,cnt)if(a[i].x>=k)ans=max(ans,a[i].y);
103     for0(i,tot)t[i][0][0]=t[i][0][1]=t[i][0][2]=t[i][1][0]=t[i][1][1]=t[i][1][2]=0;
104     tot=0;
105     for4(i,x)if(!del[y])
106     {
107         sum=s[y];rt=0;
108         getrt(y,x);
109         work(rt);
110     }
111 }   
112 int main()
113 {
114    freopen("input.txt","r",stdin);
115    freopen("output.txt","w",stdout);
116    n=read();k=read();
117    for1(i,n)v[i]=read();
118    for1(i,n)w[i]=read();
119    for1(i,n-1)add(read(),read());
120    tot=0;
121    sum=n;
122    f[rt=0]=inf;
123    getrt(1,0);
124    work(rt);
125    for1(i,n)if(v[i]>=k)ans=max(ans,w[i]);
126    cout<<ans<<endl;
127    return 0;
128 }
View Code

 

A1486. 树(王康宁)

标签:

原文地址:http://www.cnblogs.com/zyfzyf/p/4351874.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!