论文题: HUSTOJ 1912: [USACO 6.1.3]奶牛异或
http://hustoj.sinaapp.com/problem.php?id=1912
武森《浅谈信息学竞赛中的“0”和“1”》——真的是浅谈啊,亲!
本人一直觉得论文讲的有点不清不楚的,但是思路还是给我们的了,鉴于网上没有代码,我就很开心的贴上来了。。。
思路总体来讲是 异或! 建树! 化成二进制! 找1最多的!
以上。
1 #include<cstdio>
2 #include<cstdlib>
3 #include<cmath>
4 #include<climits>
5 #include<iostream>
6 #include<cstring>
7 using namespace std;
8 #define N 100010
9 #define M 1<<22
10 #define MAXN 20
11 int sum[N],n,go[M];
12 int find(int x,int c,int k){
13 if(k==-1) return go[x];
14 int wh=x<<1|1;
15 if(!go[wh]||(go[wh^1]&&(c&(1<<k)))) wh^=1;
16 return find(wh,c,k-1);
17 }
18 void up(int x,int i,int k){
19 go[x]=1;
20 if(k==-1){
21 go[x]=i;
22 return ;
23 }
24 if(sum[i]&(1<<k)) up(x<<1|1,i,k-1);
25 else up(x<<1,i,k-1);
26 }
27 int main(){
28 int ans,l,r,a;
29 sum[0]=0;
30 while(scanf("%d",&n)!=EOF){
31 for(int i=1;i<=n;++i){
32 scanf("%d",&sum[i]);
33 sum[i]^=sum[i-1];
34 }
35 memset(go,0,sizeof(go));
36 up(1,1,MAXN);
37 ans=sum[1],l=r=1;
38 for(int i=2;i<=n;++i){
39 if(sum[i]>ans){
40 l=1,r=i;
41 ans=sum[i];
42 }
43 int id=find(1,sum[i],MAXN);
44 if(ans<(sum[id]^sum[i])||
45 (ans==(sum[i]^sum[id])&&i==r)){
46 r=i,l=id+1;
47 ans=sum[id]^sum[i];
48 }
49 up(1,i,MAXN);
50 }
51 printf("%d %d %d\n",ans,l,r);
52 }
53 return 0;
54 }