D. Ehab and the Expected XOR Problem(思维)

题目链接:

https://codeforces.com/contest/1174/problem/D

题目大意:

给你n和x,让你构造一个序列使得任何一个连续子序列的异或和不等于0并且不等于x。这个序列中的数的范围是[1,(1<<n)-1],问你最长这个序列为多少,然后输出这个序列。

具体思路:

题解:https://codeforces.com/blog/entry/67388

对于第一个条件,任何一个连续子序列的异或和不等于0,等价于任意两个前缀的异或和不等于0,因为任意两个前缀和能凑出所有的连续子序列。任意两个前缀和的异或和不等于0等价于

任意两个前缀和不存在相等的情况。

对于第二个条件,具体的解题思路和第一个相等。也就是任何一个连续子序列的异或和不等于x,也就是两个前缀的异或和不等于x。

所以,我们可以枚举前缀,每一次判断当前的前缀是否合法就可以了。

AC代码:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 # define ll long long
 4 # define inf 0x3f3f3f3f
 5 # define ll_inf (1ll<<60)
 6 # define lson l,mid,rt<<1
 7 # define rson mid+1,r,rt<<1|1
 8 const int maxn = 2e6+100;
 9 const int  N = 15;
10 const int mod = 1e9+7;
11 vector<int>q;
12 map<int,int>vis;
13 int main()
14 {
15     int n,x,maxstate;
16     scanf("%d %d",&n,&x);
17     maxstate=(1<<n)-1;
18     vis[0]=1;
19     int pre=0;
20     for(int i=1; i<=maxstate; i++)
21     {
22         if(vis[i^x])
23             continue;
24         vis[i]=1;
25         q.push_back(i^pre);// 因为枚举的是前缀,但是这里存储的是当前这个数是多少
26         pre=i;
27     }
28     int len=q.size();
29     printf("%d\n",len);
30     for(int i=0; i<len; i++)
31     {
32         if(i==0)
33             printf("%d",q[i]);
34         else
35             printf(" %d",q[i]);
36     }
37     printf("\n");
38     return 0;
39 }

猜你喜欢

转载自www.cnblogs.com/letlifestop/p/10972193.html