zoukankan      html  css  js  c++  java
  • A1486. 树(王康宁)

    题目: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
  • 相关阅读:
    Netty快速入门(09)channel组件介绍
    Netty快速入门(08)ByteBuf组件介绍
    Netty快速入门(07)Netty入门例子
    Netty快速入门(06)Netty介绍
    Netty快速入门(05)Java NIO 介绍-Selector
    Netty快速入门(04)Java NIO 介绍-Channel
    Netty快速入门(03)Java NIO 介绍-Buffer
    Netty快速入门(02)Java I/O(BIO)介绍
    Netty快速入门(01)Linux I/O模型介绍
    老虎集团【4面】
  • 原文地址:https://www.cnblogs.com/zyfzyf/p/4351874.html
Copyright © 2011-2022 走看看