标签:space insert down ++ long zoj 枚举 void trie
从高位到地位建立字典树,贪心查询。
#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;
}
要求$(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;
}
正做一遍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;
}
标签:space insert down ++ long zoj 枚举 void trie
原文地址:http://www.cnblogs.com/foreignbill/p/7858039.html