• 01字典树


    Hdu 4825

    从高位到地位建立字典树,贪心查询。

    #include <bits/stdc++.h>
    
    using namespace std;
    const int maxn = 100000+5;
    typedef long long ll;
    ll bin[35];
    int n,m;
    ll a[maxn],x;
    
    struct trie{
    	int cnt;
    	int ch[maxn*35][2];
    	ll val[maxn*35];
    	void init(){
    		cnt=1;
    		memset(ch[0],0,sizeof ch[0]);
    	}
    	void insert(ll a){
    		int u=0;
    		for(int i=32;i>=0;i--){
    			ll t=a&bin[i];t>>=i;
    			if(!ch[u][t]){
    				memset(ch[cnt],0,sizeof ch[cnt]);
    				val[cnt]=0;
    				ch[u][t]=cnt++;
    			}
    			u=ch[u][t];
    		}
    		val[u]=a;
    	}
    	ll query(ll a){
    		int u=0;
    		for(int i=32;i>=0;i--){
    			ll t=a&bin[i];t>>=i;
    			if(ch[u][t^1]) u=ch[u][t^1];
    			else u=ch[u][t];
    		}
    		return val[u];
    	}
    }Trie;
    
    int main(){
    	//freopen("in.txt","r",stdin);
    	bin[0]=1;for(ll i=1;i<=35;i++) bin[i]=bin[i-1]*2ll;
    	int T,cas=1;
    	for(cin>>T,cas=1;cas<=T;cas++){
    		scanf("%d%d",&n,&m);
    		Trie.init();
    		for(int i=1;i<=n;i++){
    			scanf("%lld",&x);
    			Trie.insert(x);
    		}
    		printf("Case #%d:
    ",cas);
    		for(int i=1;i<=m;i++){
    			scanf("%lld",&x);
    			printf("%lld
    ",Trie.query(x));
    		}
    	}
    	return 0;
    }
    

    Hdu 5536

    要求$(S_i+S_j) xor S_k$最大。
    枚举$S_i$和$S_j$将其从Trie中删除,然后贪心查询。
    复杂度$O(n^2log n)$.

    #include <bits/stdc++.h>
    
    using namespace std;
    const int maxn = 10000+5;
    typedef long long ll;
    ll bin[35];
    int n,m;
    ll a[maxn],x;
    
    template<typename T> inline void read(T &x){
    x=0;T f=1;char ch;do{ch=getchar();if(ch=='-')f=-1;}while(ch<'0'||ch>'9');do x=x*10+ch-'0',ch=getchar();while(ch<='9'&&ch>='0');x*=f;
    }
    template<typename A,typename B> inline void read(A&x,B&y){read(x);read(y);}
    template<typename A,typename B,typename C> inline void read(A&x,B&y,C&z){read(x);read(y);read(z);}
    template<typename A,typename B,typename C,typename D> inline void read(A&x,B&y,C&z,D&w){read(x);read(y);read(z);read(w);}
    
    struct trie{
    	int cnt;
    	int ch[maxn*35][2];
    	ll val[maxn*35];
    	int ts[maxn*35];
    	inline void init(){
    		cnt=1;
    		memset(ch[0],0,sizeof ch[0]);
    		ts[0]=0;
    		//memset(ts,0,sizeof ts);
    	}
    	inline void insert(ll a){
    		int u=0;
    		for(int i=32;i>=0;i--){
    			ll t=a&bin[i];t>>=i;
    			if(!ch[u][t]){
    				memset(ch[cnt],0,sizeof ch[cnt]);
    				val[cnt]=0;
    				ts[cnt]=0;
    				ch[u][t]=cnt++;
    			}
    			u=ch[u][t];
    			ts[u]++;
    		}
    		val[u]=a;
    	}
    	inline void del(ll a){
    		int u=0;
    		for(int i=32;i>=0;i--){
    			ll t=a&bin[i];t>>=i;
    			u=ch[u][t];
    			ts[u]--;
    		}
    	}
    	inline ll query(ll a){
    		int u=0;
    		for(int i=32;i>=0;i--){
    			ll t=a&bin[i];t>>=i;
    			if(ch[u][t^1]&&ts[ch[u][t^1]]) u=ch[u][t^1];
    			else u=ch[u][t];
    		}
    		return val[u]^a;
    	}
    }Trie;
    
    int main(){
    	//freopen("in.txt","r",stdin);
    	bin[0]=1;for(ll i=1;i<=35;i++) bin[i]=bin[i-1]*2ll;
    	int T,cas=1;
    	for(cin>>T,cas=1;cas<=T;cas++){
    		scanf("%d",&n);
    		Trie.init();
    		for(int i=1;i<=n;i++){
    			read(a[i]);
    			Trie.insert(a[i]);
    		}
    		ll mx=0;
    		for(int i=1;i<=n;i++)
    			for(int j=i+1;j<=n;j++){
    				Trie.del(a[i]);Trie.del(a[j]);
    				mx=max(mx,Trie.query(a[i]+a[j]));
    				Trie.insert(a[i]);Trie.insert(a[j]);
    			}
    		printf("%lld
    ",mx);
    	}
    	return 0;
    }
    

    Bzoj 4260

    正做一遍dp,倒着做一遍dp。类似合唱队型。

    #include <bits/stdc++.h>
    
    using namespace std;
    const int maxn = 400000+5;
    typedef long long ll;
    int bin[31];
    int n,m;
    int a[maxn],x;
    int dp[maxn],df[maxn];
    
    template<typename T> inline void read(T &x){
    x=0;T f=1;char ch;do{ch=getchar();if(ch=='-')f=-1;}while(ch<'0'||ch>'9');do x=x*10+ch-'0',ch=getchar();while(ch<='9'&&ch>='0');x*=f;
    }
    
    template<typename A,typename B> inline void read(A&x,B&y){read(x);read(y);}
    template<typename A,typename B,typename C> inline void read(A&x,B&y,C&z){read(x);read(y);read(z);}
    template<typename A,typename B,typename C,typename D> inline void read(A&x,B&y,C&z,D&w){read(x);read(y);read(z);read(w);}
    
    struct trie{
        int cnt;
        int ch[maxn*31][2];
        int val[maxn*31];
        void init(){
            cnt=1;
            memset(ch[0],0,sizeof ch[0]);
        }
        void insert(int a){
            int u=0;
            for(int i=32;i>=0;i--){
                int t=a&bin[i];t>>=i;
                if(!ch[u][t]){
                    memset(ch[cnt],0,sizeof ch[cnt]);
                    val[cnt]=0;
                    ch[u][t]=cnt++;
                }
                u=ch[u][t];
            }
            val[u]=a;
        }
        int query(int a){
            int u=0;
            for(int i=32;i>=0;i--){
                int t=a&bin[i];t>>=i;
                if(ch[u][t^1]) u=ch[u][t^1];
                else u=ch[u][t];
            }
            return val[u]^a;
        }
    }Trie;
    
    int main(){
        //freopen("in.txt","r",stdin);
        bin[0]=1;for(int i=1;i<=35;i++) bin[i]=bin[i-1]*2;
        read(n);
        for(int i=1;i<=n;i++)
            read(a[i]);
        Trie.init();
        Trie.insert(0);
        x=0;
        for(int i=1;i<=n;i++){
            x=x^a[i];
            dp[i]=Trie.query(x);
            Trie.insert(x);
        }
        Trie.init();
        Trie.insert(0);
        x=0;
        for(int i=n;i>=1;i--){
            x^=a[i];
            df[i]=Trie.query(x);
            Trie.insert(x);
        }
        ll mx=0;
        ll res=0;
        for(int i=1;i<=n;i++){
            mx=max(mx,(ll)dp[i]);
            res=max(res,mx+df[i+1]);
        }
        cout<<res<<endl;
        return 0;
    }
    

    codeforces 842 D

    建好trie树后,建好1-3e5的字典树,插入修改标记。贪心查询。

    对于修改,只需要按位看需不需要倒置就行。

    #include<bits/stdc++.h>
    
    #define lc (tire[id][0])
    #define rc (tire[id][1])
    
    using namespace std;
    
    template<typename T> inline void read(T &x){
    x=0;T f=1;char ch;do{ch=getchar();if(ch=='-')f=-1;}while(ch<'0'||ch>'9');do x=x*10+ch-'0',ch=getchar();while(ch<='9'&&ch>='0');x*=f;
    }
    
    template<typename A,typename B> inline void read(A&x,B&y){read(x);read(y);}
    template<typename A,typename B,typename C> inline void read(A&x,B&y,C&z){read(x);read(y);read(z);}
    
    const int maxn = 6001000;
    const int maxdep = 19;
    
    bool rev[maxn];
    int cnt[maxn];
    int tire[maxn][2];
    int rt,tot;
    int build(int dep){
        int now=tot++;
        if(dep>=0){
            tire[now][0]=build(dep-1);
            tire[now][1]=build(dep-1);
        }
        return now;
    }
    int push_UP(int id){
        cnt[id]=min(cnt[lc],cnt[rc]);
    }
    int update(int id,int dep,int x){
        if(dep==-1){
            cnt[id]++;
            return 0;
        }
        int t=(x>>dep&1);
        update(tire[id][t],dep-1,x);
        push_UP(id);
    }
    void solve(){
        int ans=0;
        int now=rt;
        for(int i=maxdep;i>=0;i--){
            if(rev[i]){
                if(cnt[tire[now][1]]==0){
                    now=tire[now][1];
                } else {
                    now=tire[now][0];
                    ans+=(1<<i);
                }
            } else {
                if(cnt[tire[now][0]]==0){
                    now=tire[now][0];
                } else {
                    now=tire[now][1];
                    ans+=(1<<i);
                }
            }
        }
        printf("%d
    ",ans);
    }
    int n,m;
    int main(){
    	int x; 
        rt=build(maxdep);
        read(n,m); 
        for(int i=1;i<=n;i++){
            read(x);
            update(rt,maxdep,x);
        }
        for(int ii=1;ii<=m;ii++){
            read(x);
            for(int i=maxdep;i>=0;i--){
                if(x>>i&1){
                    rev[i]^=1;
                }
            }
            solve();
        }
        return 0;
    }
    
  • 相关阅读:
    程序员的四个阶段
    2010Year Plans
    HttpHandler HttpModule入门篇
    Lucene.net索引文件的并发访问和线程安全性
    stream流写到MemoryStream内存流引发得问题
    ASP.NET 2.0 多文件上传小经验
    HTML 迷魂灯
    如何在Windows下搭建Android开发环境
    利用Lucene.net搭建站内搜索(4)数据检索
    数据加密和解密
  • 原文地址:https://www.cnblogs.com/foreignbill/p/7858039.html
Copyright © 2020-2023  润新知