01字典樹
阿新 • • 發佈:2017-11-19
getchar() pen 復雜 字典 ret sin hdu char pac
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:\n",cas); for(int i=1;i<=m;i++){ scanf("%lld",&x); printf("%lld\n",Trie.query(x)); } } return 0; }
Hdu 5536
要求$(S_i+S_j) xor S_k$最大。
枚舉$S_i$和$S_j$將其從Trie中刪除,然後貪心查詢。
復雜度$O(n^2\log 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\n",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; }
01字典樹