【题解】
理解得迷迷糊糊。。。
一些准备操作就不说了吧。。
首先对于当前的第i个数,贪心思想按二进制位从高到低考虑。
若当前第j位是1,不管异或0还是1,这一位的贡献肯定是1<<j,不考虑??
对于当前位是0的情况,你只要考虑是否有数 包含 前面几位高位的被异或出来的1 的情况下,当前位也是1,那么就异或上当前的1,加上当前的1的贡献,也就是答案加上2<<j。
这里有个细节,处理第j位的时候,先不用管低位是否被影响到(可以思考一下)。
主要是考虑怎么求出是否有满足条件的数。
这个只要预处理出一个数组f[sta],表示状态集包含sta的出现最早的位置,对于之后关于第i位的一些询问,只要判断是否f[sta]<=i就行,也就是寻求的数是否在i之前出现。(dp一下即可)
我也不知道我在讲什么。。若是不嫌弃蒟蒻的题解的话。。边看代码边食用吧?。
【代码】
1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 using namespace std; 5 const int N=300005; 6 const int S=1100005; 7 int n,x,now; 8 int f[S],a[N]; 9 int main() 10 { 11 scanf("%d",&n); 12 memset(f,0x3f,sizeof(f)); 13 f[0]=0; 14 for (int i=1;i<=n;++i) 15 { 16 scanf("%d",&a[i]); 17 a[i]^=a[i-1]; 18 f[a[i]]=min(f[a[i]],i); 19 } 20 for (int i=0;i<20;++i) 21 for (int j=0;j<1<<20;++j) 22 if (!(j>>i&1)) f[j]=min(f[j],f[j|1<<i]); 23 for (int i=1;i<=n;++i) 24 { 25 now=0; 26 for (int j=19;~j;--j) 27 if (!(a[i]>>j&1) && f[now|1<<j]<=i) now|=1<<j; 28 printf("%d\n",now+now+a[i]); 29 } 30 return 0; 31 }
原文地址:https://www.cnblogs.com/Bleacher/p/8659336.html
时间: 2024-10-08 18:42:33