12pts求调
查看原帖
12pts求调
596437
Raisen_zx楼主2024/7/24 23:27

rt,其实是 RE 了7个点,WA了两个点

#include<cstdio>
#include<cctype>
#include<algorithm>
#define ls(p) tr[(p)].son[0]
#define rs(p) tr[(p)].son[1]
#define gc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<20,stdin),p1==p2)?EOF:*p1++)
using namespace std;
typedef long long ll;
char buf[1<<20],*p1=buf,*p2=buf;
template<typename type>
inline void read(type &x)
{
    x=0;bool flag=0;char ch=gc();
    while(!isdigit(ch)) flag=ch=='-',ch=gc();
    while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=gc();
    flag?x=-x:0;
}
const int MAXN=4e4+10;
int n,head[MAXN],rt[MAXN],son[MAXN],siz[MAXN],fa[MAXN],idx,cnte,dfn[MAXN],pdfn;
ll pre[MAXN],in[MAXN],out[MAXN];
int dfnx[MAXN],tmpo,x,y,stk[4],tail;
ll ans;
struct Edge
{
    int to,nxt,val;
}e[MAXN<<1];
struct Trie
{
    int son[2],ed;
}tr[MAXN*60];
bool vis[MAXN];
inline void link(int u,int v,int w)
{
    e[++cnte]={v,head[u],w};
    head[u]=cnte;
}
void dfs1(int u,int fth)
{
    fa[u]=fth,siz[u]=1;
    for(int i=head[u],v;i;i=e[i].nxt)
    {
        v=e[i].to;
        if(v==fth) continue;
        pre[v]=pre[u]^e[i].val;
        dfs1(v,u);
        siz[u]+=siz[v];
        if(siz[v]>siz[son[u]]) son[u]=v;
        
    }
}
inline void insert(int p,ll v)
{
    int tmp=p;
    p=rt[p];
    for(ll i=31;i>=0;--i)
    {
        ll d=(v>>i)&1;
        if(!tr[p].son[d]) tr[p].son[d]=++idx;
        p=tr[p].son[d];
    }
    tr[p].ed=tmp;
}
inline ll find(int p,ll v)
{
    ll res=0;
    for(ll i=31;i>=0;--i)
    {
        int d=((v>>i)&1)^1;
        if(!tr[p].son[d]) d^=1;
        p=tr[p].son[d];
        res=(res<<1)|d;
    }
    return v^res;
}
inline int find_id(int p,int v)
{
    for(int i=31;i>=0;--i)
    {
        int d=((v>>i)&1)^1;
        if(!tr[p].son[d]) d^=1;
        p=tr[p].son[d];
    }
    return tr[p].ed;
}
int merge(int u,int v)
{
    if(!u||!v) return u|v;
    ls(u)=merge(ls(u),ls(v));
    rs(u)=merge(rs(u),rs(v));
    return u;
}
void calc(int u)
{
    dfnx[++pdfn]=u;
    dfn[u]=pdfn;
    if(son[u]) calc(son[u]);
    for(int i=head[u],v;i;i=e[i].nxt)
    {
        v=e[i].to;
        if(v!=son[u]&&v!=fa[u]) calc(v);
    }
}
void dfs2(int u)
{
    rt[u]=++idx;
    insert(u,pre[u]);
    if(son[u])
    {
        dfs2(son[u]);
        in[u]=max(in[son[u]],find(rt[son[u]],pre[u]));
        rt[u]=merge(rt[u],rt[son[u]]);
    }
    for(int i=head[u],v;i;i=e[i].nxt)
    {
        v=e[i].to;
        if(v==fa[u]||v==son[u]) continue;
        dfs2(v);
        in[u]=max(in[u],in[v]);
        for(int j=dfn[v];j<=dfn[v]+siz[v]-1;++j)
        {
            int k=dfnx[j];
            in[u]=max(in[u],find(rt[u],pre[k]));
        }
        rt[u]=merge(rt[u],rt[v]);
    }
}
inline void bj(int u)
{
    while(u) vis[u]=1,u=fa[u];
}
void solve(int u)
{
    tail=0;
    if(!vis[u]) return;
    ll tmp=out[u];
    if(u!=1)
    {
        tmp=max(tmp,find(rt[u],pre[u]));
    }
    insert(rt[u],pre[u]);
    for(int i=head[u],v;i;i=e[i].nxt)
    {
        v=e[i].to;
        if(v==fa[u]) continue;
        else if(vis[v])
        {
            stk[++tail]=v;
            continue;
        }
        else{
            for(int j=dfn[v],k;j<=dfn[v]+siz[v]-1;++j)
            {
                k=dfnx[j];
                tmp=max(tmp,find(rt[u],pre[k]));
            }
            rt[u]=merge(rt[u],rt[v]);
        }
    }
    if(tail==1)
    {
        rt[stk[1]]=++idx;
        rt[stk[1]]=merge(rt[stk[1]],rt[u]);
        out[stk[1]]=tmp;
        solve(stk[1]);
    }
    if(tail==2)
    {
        int tmp1=rt[stk[1]],tmp2=rt[stk[2]];
        out[stk[1]]=tmp,out[stk[2]]=tmp;
        for(int i=1;i<=2;++i)
        {
            int t=stk[3-i];
            for(int j=dfn[t],k;j<=dfn[t]+siz[t]-1;++j)
            {
                k=dfnx[j];
                out[stk[i]]=max(out[stk[i]],find(rt[u],pre[k]));
            }
        }
        rt[stk[1]]=++idx,rt[stk[2]]=++idx;
        rt[stk[1]]=merge(rt[stk[1]],rt[u]);
        rt[stk[2]]=merge(rt[stk[2]],rt[u]);
        rt[stk[1]]=merge(rt[stk[1]],tmp2);
        rt[stk[2]]=merge(rt[stk[2]],tmp1);
        solve(stk[1]);
        solve(stk[2]);
    }
}
int main()
{
    read(n);
    // printf("%d\n",n);
    for(int i=1,a,b,w;i<n;++i)
    {
        read(a),read(b),read(w);
        link(a,b,w),link(b,a,w);
    }
    dfs1(1,0);
    calc(1);
    dfs2(1);
    for(int i=1;i<=n;++i)
    {
        int tmp=find(rt[1],pre[i]);
        if(tmp>tmpo) tmpo=tmp,x=i,y=find_id(rt[1],pre[i]);
    }
    // printf("%d %d\n",x,y);
    bj(x),bj(y);
    for(int i=1;i<=n;++i) if(!vis[i]) out[i]=tmpo;
    rt[1]=++idx;
    solve(1);
    for(int i=2;i<=n;++i) ans=max(ans,in[i]+out[i]);
    printf("%d\n",ans);
    return 0;
}
2024/7/24 23:27
加载中...