[TJOI2018]xor BZOJ5338 可持久trie

遇到水题了。贼嗨森。

题目传送门

题意简单,就不多解释了。

可持久化trie树模板*2,就A了。

第一棵树表示从根到该点,第二棵树依靠dfs序建立。然后就是注意空间问题,我想省一下空间,结果31层的树存不下,RE了3遍才找到,把31改成30就A了,,

#include<bits/stdc++.h>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<queue>
#include<deque>
#include<list>
#include<set>
#include<vector>
#include<iostream>
#define ll int
#define re register
#define inf 0x3f3f3f3f
#define inl inline
#define sqr(x) (x*x)
//#define eps 1e-8
#define debug printf("debug\n");
//#pragma comment(linker, "/STACK:1024000000,1024000000")
//#pragma GCC optimize (2)
//#pragma G++ optimize (2)
using namespace std;
const ll mod=2520;
const ll MAXN=1e5+10;
const ll MAXM=(5e4+10)*4;
inl ll read() {
    re ll x = 0; re int f = 1;
    char ch = getchar();
    while(ch<'0'||ch>'9') { if(ch== '-' ) f = -1; ch = getchar(); }
    while(ch>='0'&&ch<='9') {x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
    return x * f;
}
inl char readc() {
    char ch=getchar();
    while(('z'<ch||ch<'a')&&('Z'<ch||ch<'A')) ch=getchar();
    return ch;
}
inl void write(re ll x){
    if(x>=10)write(x/10);
    putchar(x%10+'0');
}
inl void writeln(re ll x){
    if(x<0) {x=-x;putchar('-');}
    write(x); puts("");
}
inl ll gcd(re ll x,re ll y){while(y^=x^=y^=x%=y);return x;}
inl ll Lcm(re ll a,re ll b) {return a/gcd(a,b)*b;}
inl void FR() {
    freopen(".in","r",stdin);
    freopen(".out","w",stdout);
}
inl void FC() {
    fclose(stdin);
    fclose(stdout);
}
struct edge {
    ll u,v,nxt;
}e[MAXN<<1];
ll ssw[MAXN],n,cnt,head[MAXN],root1[MAXN],root2[MAXN];
inl void adde(ll u,ll v) {
    e[++cnt].u=u;e[cnt].v=v;
    e[cnt].nxt=head[u];head[u]=cnt;
}
ll T_cnt;
struct Node {
    ll son[2],cnt;
}Tree[100005<<6];
ll insert(ll pre,ll x) {
    re ll t=++T_cnt;Tree[t]=Tree[pre];
    ll now=t;Tree[now].cnt++;
    for(re ll i=30;~i;i--) {
        if((x>>i)&1) {
            Tree[now].son[1]=++T_cnt;
            now=Tree[now].son[1];
            pre=Tree[pre].son[1];
        }
        else {
            Tree[now].son[0]=++T_cnt;
            now=Tree[now].son[0];
            pre=Tree[pre].son[0];
        }
        Tree[now]=Tree[pre];Tree[now].cnt++;
    }
    return t;
}
ll topn[MAXN],out[MAXN],d_tot,dfn[MAXN],f[MAXN][30],depth[MAXN];
void dfs(ll x,ll fa) {
    root1[x]=insert(root1[fa],ssw[x]);
    f[x][0]=fa;depth[x]=depth[fa]+1;
    for(re ll i=1;i<=25;i++) f[x][i]=f[f[x][i-1]][i-1];
    topn[++d_tot]=x;dfn[x]=d_tot;
    for(re ll h=head[x];h;h=e[h].nxt) {
        re ll v=e[h].v;
        if(v==fa) continue ;
        dfs(v,x);
    }
    out[x]=d_tot;
}
ll lca(ll a,ll b) {
    if(depth[b]<depth[a]) swap(a,b);
    for(re ll i=25;~i;i--) {
        if(depth[f[b][i]]<depth[a]) continue ;
        b=f[b][i];
    }
    if(a==b) return a;
    for(re ll i=25;~i;i--) {
        if(f[a][i]==f[b][i]) continue ;
        a=f[a][i],b=f[b][i];
    }
    return f[a][0];
}
ll query(ll l,ll r,ll x) {
    ll ans=0;
    for(re ll i=30;~i;i--) {
        ll p=(x>>i)&1;
        if(Tree[Tree[r].son[p^1]].cnt-Tree[Tree[l].son[p^1]].cnt) {
            l=Tree[l].son[p^1],r=Tree[r].son[p^1],ans|=(1<<i);
        }
        else {
            l=Tree[l].son[p],r=Tree[r].son[p];
        }
    }
    return ans;
}
int main() {
//  FR();
    n=read();re ll Q=read();
    for(re ll i=1;i<=n;i++) ssw[i]=read();
    for(re ll i=1;i<n;i++) {
        re ll u=read(),v=read();
        adde(u,v);adde(v,u);
    }
    dfs(1,0);
    for(re ll i=1;i<=n;i++) {root2[topn[i]]=insert(root2[topn[i-1]],ssw[topn[i]]);}
    for(re ll i=1;i<=Q;i++) {
        re ll opt=read();
        if(opt==1) {
            re ll x=read(),y=read();
            writeln(query(root2[topn[dfn[x]-1]],root2[topn[out[x]]],y));
        }
        else if(opt==2) {
            re ll x=read(),y=read(),z=read();
            ll ssx=lca(x,y),ssy=f[ssx][0];
            writeln(max(query(root1[ssy],root1[y],z),query(root1[ssy],root1[x],z)));
        }
    }
//  FC();
    return 0;
}
View Code

猜你喜欢

转载自www.cnblogs.com/20020723YJX/p/9386474.html
今日推荐