zoukankan      html  css  js  c++  java
  • [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
    ");
    //#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
  • 相关阅读:
    SpringBoot集成logback.xml日志配置文件找不到错误
    两个List集合如何去重,取交集,并集,差集
    分转元工具类
    Redis(二十九)PHP 使用 Redis
    Redis学习(二十八)Java 使用 Redis
    Redis学习(二十七)Redis 分区
    Redis学习(二十六)Redis 管道技术
    面试题
    Android 自动化测试
    Inner Functions
  • 原文地址:https://www.cnblogs.com/20020723YJX/p/9386474.html
Copyright © 2011-2022 走看看