hdu 4776 Ants Trie树+乱搞

参考:http://www.csdn123.com/html/itweb/20131111/216497.htm

代码写的真心挫,在看了题解的算法后,自己去实现,调了好长时间才弄对。代码能力真是不行,难怪区域赛被虐成狗。。。

算法,是参照以上链接的,不多提,就说下我写的时候遇到的问题:

首先,在找次大的时候,不要写成递归的,我最开始是写递归的,但是死活都是爆栈,只好代码都删了重新写的。。。

然后,由于到根的异或和可以相同,所以在插入到字典树中的时候要记录数目,然后找次大的时候要考虑好这个细节!如果找以u为起点,v为终点的次大的时候,如果找到的叶子是u所在的叶子的时候的情况需要怎么处理。。。

代码:

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
const int maxn = 100100;
typedef long long ll;
struct Side{
    int to,next;
    ll w;
}side[maxn*2];
int node[maxn],top;
ll val[maxn];
void add_side(int u,int v,ll w){
    side[top]=(Side){v,node[u],w};node[u]=top++;
    side[top]=(Side){u,node[v],w};node[v]=top++;
}
bool vis[maxn];
void dfs(int u){
    vis[u]=true;
    for(int i=node[u];i!=-1;i=side[i].next){
        int v=side[i].to;
        if(vis[v])continue;
        val[v]=val[u]^side[i].w;
        dfs(v);
    }
}
ll bit[60];
int end[maxn],root=1,cnt;
struct Node{
    int ch[2];
    int cnt;
    int fa;
    ll val;
}trie[maxn*60];
struct E{
    ll val;
    int u,x,cnt;
    friend bool operator < (const E &a,const E &b){
        return a.val<b.val;
    }
};
priority_queue<E>q;
ll ans[2*maxn];
int find_max(int p,ll val,int b){
    for(int i=b;i>=0;i--){
        int t=(val&bit[i])?1:0;
        if(trie[p].ch[t^1])p=trie[p].ch[t^1];
        else p=trie[p].ch[t];
    }
    return p;
}
bool find_next(E &e){
    if(e.cnt>0){
        e.cnt--;
        return true;
    }
    if(e.x==end[e.u])return false;

    int u=e.u,x=e.x,cnt=e.cnt;
    //cout<<u<<' '<<x<<' '<<endl;
    int b=0;
    while(x!=root){
        int fa=trie[x].fa;
        int b1=(val[u]&bit[b])?1:0;
        int b2=(trie[x].val&1)?1:0;
        if(b1^b2){
            if(trie[fa].ch[b1]){
                x=find_max(trie[fa].ch[b1],val[u],b-1);
                break;
            }else x=fa;
        }else{
            x=fa;
        }
        b++;
    }
    e.x=x;
    e.cnt=trie[x].cnt-1;
    e.val=val[u]^trie[x].val;
    if(end[u]==x){
        e.cnt--;
        if(e.cnt<0)return false;
    }
    return true;
}
int main(){
    bit[0]=1;
    for(int i=1;i<60;i++)bit[i]=bit[i-1]*2;
    int n;
    while(~scanf("%d",&n)&&n){
        while(!q.empty())q.pop();
        memset(node,-1,sizeof(node));
        memset(ans,-1,sizeof(ans));
        memset(vis,false,sizeof(vis));
        top=0;
        for(int i=1;i<n;i++){
            int u,v;ll w;
            scanf("%d%d",&u,&v);cin>>w;
            add_side(u,v,w);
        }
        val[1]=0;
        dfs(1);
        trie[root].ch[0]=trie[root].ch[1]=0;
        trie[root].cnt=trie[root].fa=0;
        cnt=2;
        E tmp;
        for(int i=1;i<=n;i++){
            int p=root;
            for(int j=59;j>=0;j--){
                int b1=(bit[j]&val[i])?1:0;
                if(trie[p].ch[b1]==0){
                    trie[cnt].ch[0]=trie[cnt].ch[1]=0;
                    trie[cnt].val=trie[p].val*2+b1;
                    trie[cnt].fa=p;
                    trie[cnt].cnt=0;
                    trie[p].ch[b1]=cnt++;
                }
                p=trie[p].ch[b1];
                //cout<<trie[p].val<<endl;
            }
            trie[p].cnt++;
            end[i]=p;
        }
        for(int i=1;i<=n;i++){
            int x=find_max(root,val[i],59);
            tmp.x=x;
            tmp.u=i;
            tmp.cnt=trie[x].cnt-1;
            tmp.val=trie[x].val^val[i];
            if(end[tmp.u]==x)tmp.cnt--;
            //printf("%d %lld %lld\n",i,val[i],tmp.val);
            if(tmp.x!=end[i]||tmp.cnt>=0)q.push(tmp);
        }
        //tmp = q.top();
        //printf("%lld\n",tmp.val);
        for(int k=1;k<=200000&&!q.empty();k++){
            tmp=q.top();q.pop();
            ans[k]=tmp.val;
            //printf("%d %lld\n",k,ans[k]);
            if(find_next(tmp))q.push(tmp);
        }
        int m;
        scanf("%d",&m);
        for(int i=0;i<m;i++){
            int k;
            scanf("%d",&k);
            printf("%I64d\n",ans[k]);
        }
    }
}
    原文作者:Trie树
    原文地址: https://blog.csdn.net/wh2124335/article/details/16829805
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞