Loading

代码-几道 Trie 树水题

洛谷P4551 最长异或路径

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef double db;
#define x first
#define y second
#define bg begin()
#define ed end()
#define pb push_back
#define mp make_pair
#define sz(a) int((a).size())
#define R(i,n) for(int i(0);i<(n);++i)
#define L(i,n) for(int i((n)-1);i>=0;--i)
const int iinf=0x3f3f3f3f;
const ll linf=0x3f3f3f3f3f3f3f3f;

//Data
const int N=1e5;
int n;

//Trie
struct trie{
    int d; trie* e[2];
    trie(int d):d(d){R(c,2) e[c]=NULL;}
    void insert(int x){
        if(!~d) return; trie* &s=e[x>>d&1];
        (s?s:s=new trie(d-1))->insert(x);
    }
    void get(int x,int &res){
        if(!~d) return;
        if(e[(x>>d&1)^1]) e[(x>>d&1)^1]->get(x,res),res|=1<<d;
        else e[x>>d&1]->get(x,res);
    }
};

//Graph
vector<pair<int,int>> adj[N];
int dep[N];
void dfs(int u,int fa){
    for(auto v:adj[u])if(v.x!=fa)
        dep[v.x]=dep[u]^v.y,dfs(v.x,u);
}

//Main
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0),cout.tie(0);
    cin>>n;
    R(i,n-1){
        int u,v,w; cin>>u>>v>>w,--u,--v;
        adj[u].pb(mp(v,w)),adj[v].pb(mp(u,w));
    }
    dfs(0,-1);
    int ns=0,res=-1;
    trie *rt=new trie(31);
    R(i,n) res=0,i?rt->get(dep[i],res):void(),
        ns=max(ns,res),rt->insert(dep[i]);
    cout<<ns<<'\n';
    return 0;
}

HNOI2004 L语言

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef double db;
#define x first
#define y second
#define bg begin()
#define ed end()
#define pb push_back
#define mp make_pair
#define sz(a) int((a).size())
#define R(i,n) for(int i(0);i<(n);++i)
#define L(i,n) for(int i((n)-1);i>=0;--i)
const int iinf=0x3f3f3f3f;
const ll linf=0x3f3f3f3f3f3f3f3f;

//Data
const int N=20,C=26;
int n,m;
map<string,bool> vis;
map<string,int> res;

//Trie
struct trie{
    int d; bool mk; trie *ch[C];
    trie(int d):d(d),mk(false){R(c,C) ch[c]=NULL;}
    void insert(const string &s){
        if(d==sz(s)) return void(mk=true);
        trie* &b=ch[s[d]-'a'];
        (b?b:b=new trie(d+1))->insert(s);
    }
};

//Main
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0),cout.tie(0);
    cin>>n>>m;
    trie* rt=new trie(0);
    R(i,n){
        static string s;
        cin>>s,rt->insert(s);
    }
    while(m--){
        static string t; cin>>t;
        if(vis[t]){
            cout<<res[t]<<'\n';
            continue;
        }
        int ns=0,len=sz(t);
        vector<bool> f(len+1);
        f[0]=true;
        R(i,len+1)if(f[i]){
            ns=i; trie *u=rt;
            for(int j=i;j<len;j++){
                if(!u->ch[t[j]-'a']) break;
                u=u->ch[t[j]-'a'];
                if(u->mk) f[j+1]=true;
            }
        }
        vis[t]=true;
        cout<<(res[t]=ns)<<'\n';
    }
    return 0;
}

TJOI2018 异或

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef double db;
#define x first
#define y second
#define bg begin()
#define ed end()
#define pb push_back
#define mp make_pair
#define sz(a) int((a).size())
#define R(i,n) for(int i(0);i<(n);++i)
#define L(i,n) for(int i((n)-1);i>=0;--i)
const int iinf=0x3f3f3f3f;
const ll linf=0x3f3f3f3f3f3f3f3f;

//Data
const int N=1e5+1;
int n,m,a[N],no[N],rt[N];

//Trie
const int T=31e5+1;
int trie_n=1,sm[T],ch[T][2];
void insert(int p,int q,int x,int d=29){
    ch[q][0]=ch[p][0],ch[q][1]=ch[p][1],sm[q]=sm[p]+1;
    if(d==-1) return; bool b=x>>d&1;
    insert(ch[p][b],ch[q][b]=trie_n++,x,d-1);
}
void get(int p,int q,int x,int &res,int d=29){
    if(d==-1) return; bool b=!(x>>d&1);
    (sm[ch[q][b]]-sm[ch[p][b]])?res|=1<<d:b=!b;
    get(ch[p][b],ch[q][b],x,res,d-1);
}

//Tree
vector<int> adj[N];
int in,d[N],fa[N],s[N],sz[N],tp[N],dfn[N];
void mson(int u){
    sz[u]=1;
    for(int v:adj[u])if(v!=fa[u]){
        d[v]=d[fa[v]=u]+1,mson(v),sz[u]+=sz[v];
        if(!~s[u]||sz[v]>sz[s[u]]) s[u]=v;
    }
}
void mtop(int u){
    no[dfn[u]=in++]=u;
    if(~s[u]) tp[s[u]]=tp[u],mtop(s[u]);
    for(int v:adj[u])if(v!=fa[u]&&v!=s[u]) mtop(tp[v]=v);
}

//Function
void get_c(int u,int v,int x,int &ns){
    int res=-1;
    for(;~u&&~v&&tp[u]!=tp[v];u=fa[tp[u]]){
        if(d[tp[u]]<d[tp[v]]) swap(u,v);
        res=0,get(rt[dfn[tp[u]]],rt[dfn[u]+1],x,res);
        ns=max(ns,res);
    }
    if(dfn[u]>dfn[v]) swap(u,v);
    res=0,get(rt[dfn[u]],rt[dfn[v]+1],x,res);
    ns=max(ns,res);
}

//Main
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0),cout.tie(0);
    cin>>n>>m;
    R(i,n) cin>>a[i];
    R(i,n-1){
        int u,v; cin>>u>>v,--u,--v;
        adj[u].pb(v),adj[v].pb(u);
    }
    R(u,n) fa[u]=s[u]=-1; mson(0),mtop(0);
    R(i,n) insert(rt[i],rt[i+1]=trie_n++,a[no[i]]);
    while(m--){
        int o,u,v,x,res=0; cin>>o,--o;
        if(o) cin>>u>>v>>x,--u,--v,get_c(u,v,x,res);
        else cin>>u>>x,--u,get(rt[dfn[u]],rt[dfn[u]+sz[u]],x,res);
        cout<<res<<'\n';
    }
    return 0;
}

十二省联考2019 异或粽子

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef double db;
#define x first
#define y second
#define bg begin()
#define ed end()
#define pb push_back
#define mp make_pair
#define sz(a) int((a).size())
#define R(i,n) for(int i(0);i<(n);++i)
#define L(i,n) for(int i((n)-1);i>=0;--i)
const int iinf=0x3f3f3f3f;
const ll linf=0x3f3f3f3f3f3f3f3f;

//Data
using uint=unsigned int;
const int N=5e5+1;
int n,m,rt[N],cnt[N]; uint a[N]; ll ns;
priority_queue<pair<uint,int>> q;

//Trie
const int T=4e7;
int trie_n=1,ch[T][2],sm[T];
void insert(int p,int q,uint x,int v,int d=31){
    sm[q]=sm[p]+v,ch[q][0]=ch[p][0],ch[q][1]=ch[p][1];
    if(d==-1) return; uint b=x>>d&1;
    insert(ch[p][b],ch[q][b]=trie_n++,x,v,d-1);
}
uint get(int p,uint x,int d=31){
    if(d==-1) return 0; uint b=!(x>>d&1);
    sm[ch[p][b]]?true:b=!b;
    return b<<d|get(ch[p][b],x,d-1);
}

//Main
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0),cout.tie(0);
    cin>>n>>m,++n;
    R(i,n) i?cin>>a[i],a[i]^=a[i-1]:a[i]=0,cnt[i]=i;
    R(i,n-1) insert(rt[i],rt[i+1]=trie_n++,a[i],1);
    R(i,n) i?q.push({get(rt[i],a[i])^a[i],i}):void();
    while(m--){
        uint x=q.top().x; int i=q.top().y; q.pop(),ns+=x;
        // cout<<a[i]<<"^"<<(x^a[i])<<'\n';
        int t=rt[i]; insert(t,rt[i]=trie_n++,x^a[i],-1);
        --cnt[i]?q.push({get(rt[i],a[i])^a[i],i}):void();
    }
    cout<<ns<<'\n';
    return 0;
}

posted @ 2020-12-26 16:37  George1123  阅读(12)  评论(0编辑  收藏  举报