您的位置:首页 > 其它

hdu 5536 Chip Factory 2015ACM/ICPC亚洲区长春站-重现赛

2016-06-17 00:41 337 查看
看到xor就想到14年做的字典树,然而我一直纠结s_i+s_j怎么处理,总感觉直接暴力会超时,最后发现n>100的case才十个。== 一开始是通过存储s_i每个bit对应在字典树上的路径来删除和恢复。然后TLE了><后来发现有一种trick就是记录每个节点的frequency,如果删除s,执行插入操作并且令s对应的路径节点的frequency-1,就可以通过frequency的正负判断s是否存在了。recover时只要执行插入操作,将路径上对应节点的frequency+1即可。

#include<iostream>
#include<stdio.h>
#include<cstdio>
#include<string>
#include<cmath>
#include<stdlib.h>
#include<algorithm>
#include<string.h>
#include<cstring>
#include<vector>
#include<queue>
#include<map>
#include<bitset>

using namespace std;
//hdu 5536
const int maxn=1024;
const int bitsz=32;
const int maxz=1024*bitsz;
int T;
int n;
int s[maxn];
int ch[maxz][2];
int val[maxz];
int sz;
int ans;
int freq[maxz];//how many numbers use this internal node
void insert(bitset<bitsz>bit,int v,int d)
{
int u=0;
for(int i=0;i<bitsz;i++)
{
int c=bit[bitsz-i-1];
//cout<<bit<<" "<<bitsz-i<<" "<<c<<endl;
if(!ch[u][c])//ch[u][0] refers to 0, ch[u][1] refers to 1
{
memset(ch[sz],0,sizeof(ch[sz]));
val[sz]=0;//it's an internal node
ch[u][c]=sz++;
}
//cout<<"u: "<<u<<" c: "<<c<<" ch: "<<ch[u][c]<<endl;
u=ch[u][c];
freq[u]+=d;
}
val[u]=v;
//cout<<"val "<<u<<" "<<val[u]<<endl;
}
void Delete(bitset<bitsz>bit,int v,int label[])//This way leads to TLE
{
int u=0;
int fa[maxz];
//int label[30];
memset(fa,0,sizeof(fa));
memset(label,0,sizeof(label));
for(int i=0;i<bitsz;i++)
{
int c=bit[bitsz-i-1];
fa[ch[u][c]]=u;//father
//cout<<fa[ch[u][c]]<<" del ";
u=ch[u][c];
//cout<<u<<endl;
}
val[u]=0;
bool flgdel=true;
for(int i=0;i<bitsz;i++)//from big bit to small bit
{
int c=bit[i];
int pre=fa[u];
//cout<<u<<" "<<fa[u]<<" here "<<pre<<" "<<c<<endl;
// if(!ch[pre][1-c])
// {
// label[pre]=ch[pre][c];
// memset(ch[pre],0,sizeof(ch[pre]));
// u=pre;
// cout<<pre<<" rev "<<label[pre]<<endl;
// }
// else
// {
// break;
// }
label[i]=ch[pre][c];
if(flgdel==true)
{
ch[pre][c]=0;
}
u=pre;
//cout<<i<<" "<<pre<<" rev "<<label[i]<<" "<<ch[pre][1-c]<<endl;
if(ch[pre][1-c])
{
flgdel=false;
}
}
}
void recover(bitset<bitsz>bit,int v,int label[])
{
//cout<<"recover"<<endl;
int u=0;
for(int i=0;i<bitsz;i++)
{
int c=bit[bitsz-i-1];
if(!ch[u][c])
{
ch[u][c]=label[bitsz-i-1];
}
u=ch[u][c];
//cout<<i<<" "<<c<<" "<<u<<endl;
}
val[u]=v;
}
int find(bitset<bitsz>bit)
{
bitset<bitsz>res(0);
int u=0;
for(int i=0;i<bitsz;i++)
{
int c=bit[bitsz-i-1];
//cout<<i<<" "<<c<<" "<<ch[u][1-c]<<endl;
int next=ch[u][1-c];
if(freq[next]<=0)
//if(!ch[u][1-c])
{
res[bitsz-i-1]=0;
u=ch[u][c];
}
else
{
res[bitsz-i-1]=1;
u=ch[u][1-c];
}

}
//cout<<" res "<<res<<endl;
int ret=res.to_ulong();
return ret;
}
int main()
{
// bitset<4>num(3);
// cout<<num[0]<<endl;
freopen("input.txt","r",stdin);
scanf("%d",&T);
for(int ca=1;ca<=T;ca++)
{
memset(s,0,sizeof(s));
memset(ch,0,sizeof(ch));
memset(val,0,sizeof(val));
memset(freq,0,sizeof(freq));
sz=1;
ans=0;
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%d",&s[i]);
bitset<bitsz>num(s[i]);
//cout<<num<<endl;
insert(num,s[i],1);
}
for(int i=0;i<n;i++)
{
bitset<bitsz>numi(s[i]);
//int labeli[bitsz];
//memset(labeli,0,sizeof(labeli));
//Delete(numi,s[i],labeli);
insert(numi,s[i],-1);
for(int j=i+1;j<n;j++)
{
int sum=s[i]+s[j];
//int labelj[bitsz];
//memset(labelj,0,sizeof(labelj));
bitset<bitsz>numj(s[j]);
bitset<bitsz>nums(sum);
insert(numj,s[j],-1);
//Delete(numj,s[j],labelj);
ans=max(ans,find(nums));
insert(numj,s[j],1);
//cout<<nums<<" here "<<find(nums)<<endl;
//recover(numj,s[j],labelj);
}
insert(numi,s[i],1);
//recover(numi,s[i],labeli);
}
printf("%d\n",ans);
}
//cout<<(500^100)<<endl;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: