3908. 【NOIP2014模拟11.1B组】吴传之火烧连营 (Standard IO)
Time Limits: 1000 ms Memory Limits: 131072 KB Special Judge
Description
【问题描述】
刘备带兵深入吴境,陆逊却避而不出,蜀军只得在山林中安营扎寨。而刘备在扎营时却犯了兵家大忌,将兵营排列成一条直线,远远看去,就像是一条串着珠子的链,美其名曰:链寨。如果吴军将领是一般人,那么这也许不算什么,而陆逊何许人也,他可是江东才子,能力不低于周瑜的一代儒将。他看到刘备这样排阵,心生一计,决定用火攻破阵。然而,火计除了要有风,选定引火点也非常重要,对于刘备的布阵,最佳引火点一定是n个兵营中的一个。而因为风水轮流转,每天的最佳引火点都不一样。我们给每个兵营定下一个固定不变的火攻值Ai,每天定下一个风水值K,对于每天的最佳引火点,显然是所有兵营中火攻值与风水值异或的结果最大的那一个兵营。然而,陆逊是个谨慎的人,他要观察时机,在m天中选定一个最佳的进攻的日期,为此他演算出了这m天每天的风水值,然后他希望你能够告诉他这m天每天最佳引火点的兵营编号。
Input
第一行n,m,代表有n个兵营,m天。
接下来一行有n个非负整数,代表这n个兵营的火攻值。
接下来一行有m个非负整数,代表这m天的风水值。
Output
输出共m行,每行输出一个整数,代表第m天最佳引火点的编号。
如果存在多个最佳引火点使得火攻值与风水值的异或值最大,请任意输出一组解即可。
Sample Input
3 2
1 2 3
4 5
Sample Output
3
2
【样例解释】
对于第1天,由于4 xor 1=5, 4 xor 2=6, 4 xor 3=7,选择第3个引火点是最佳的。
对于第2天,由于5 xor 1=4, 5 xor 2=7, 5 xor 3=6,选择第2个引火点是最佳的。
Data Constraint
对于30%数据,n<=1000,m<=1000
Time Limits: 1000 ms Memory Limits: 131072 KB Special Judge
Description
【问题描述】
刘备带兵深入吴境,陆逊却避而不出,蜀军只得在山林中安营扎寨。而刘备在扎营时却犯了兵家大忌,将兵营排列成一条直线,远远看去,就像是一条串着珠子的链,美其名曰:链寨。如果吴军将领是一般人,那么这也许不算什么,而陆逊何许人也,他可是江东才子,能力不低于周瑜的一代儒将。他看到刘备这样排阵,心生一计,决定用火攻破阵。然而,火计除了要有风,选定引火点也非常重要,对于刘备的布阵,最佳引火点一定是n个兵营中的一个。而因为风水轮流转,每天的最佳引火点都不一样。我们给每个兵营定下一个固定不变的火攻值Ai,每天定下一个风水值K,对于每天的最佳引火点,显然是所有兵营中火攻值与风水值异或的结果最大的那一个兵营。然而,陆逊是个谨慎的人,他要观察时机,在m天中选定一个最佳的进攻的日期,为此他演算出了这m天每天的风水值,然后他希望你能够告诉他这m天每天最佳引火点的兵营编号。
Input
第一行n,m,代表有n个兵营,m天。
接下来一行有n个非负整数,代表这n个兵营的火攻值。
接下来一行有m个非负整数,代表这m天的风水值。
Output
输出共m行,每行输出一个整数,代表第m天最佳引火点的编号。
如果存在多个最佳引火点使得火攻值与风水值的异或值最大,请任意输出一组解即可。
Sample Input
3 2
1 2 3
4 5
Sample Output
3
2
【样例解释】
对于第1天,由于4 xor 1=5, 4 xor 2=6, 4 xor 3=7,选择第3个引火点是最佳的。
对于第2天,由于5 xor 1=4, 5 xor 2=7, 5 xor 3=6,选择第2个引火点是最佳的。
Data Constraint
对于30%数据,n<=1000,m<=1000
对于100%数据,n<=100000,m<=100000, 0<=k,ai<=2147483647
对于n个数,建一个二进制字典树。
对于m个数,每个数二进制取反,在字典树上贪心即可。
#include
#include
#include
#include
using namespace std;
int n,m,a[100010],i,j,k,g[31],f[10000000][3],tot=1;
void trie(int num,int po,int index){
if(index==-1){
f[num][2]=po;return ;
}
int u=a[i]/g[index];
a[i]%=g[index];
if(f[num][u]==0)f[num][u]=++tot;
trie(f[num][u],po,index-1);
}
int find(int num,int val,int index){
if(index==-1)return f[num][2];
int u=val/g[index];
if(f[num][u]==0)return find(f[num][u xor 1],val % g[index],index-1);else{
return find(f[num][u],val % g[index], index-1);
}
}
int main(){freopen("3.in","r",stdin);freopen("3.out","w",stdout);
scanf("%d%d",&n,&m);
g[0]=1;
for(i=1;i<=30;i++){
g[i]=g[i-1]*2;
j+=g[i];
}
j++;
for(i=1;i<=n;i++){
scanf("%d",&a[i]);
trie(1,i,30);
}
for(i=1;i<=m;i++){
scanf("%d",&k);
k=(k^j);
printf("%d\n",find(1,k,30));
}
}