Scx117
只一眼,便辽阔了时间。

题意:给你一个数列A。将所有可能异或出的值从小到大排列。问x是第几个。ai<=1e9,n<=100000.

标程:

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstring>
 4 using namespace std;
 5 typedef long long ll;
 6 const int mod=10086;
 7 int cnt[32],n,x,tot,s[32],ans;
 8 void ins(int x)
 9 {
10     for (int i=31;i>=0;i--)
11       if ((x>>i)&1)
12         if (!cnt[i]) {cnt[i]=x;break;}
13         else  x^=cnt[i];
14 }
15 int ksm(int x,int y)
16 {
17     int res=1;
18     while (y) {if (y&1) res=(ll)res*x%mod; x=(ll)x*x%mod; y>>=1;}
19     return res;
20 }
21 int main()
22 {
23     scanf("%d",&n);
24     for (int i=1;i<=n;i++) scanf("%d",&x),ins(x);
25     for (int i=0;i<=31;i++)
26       if (cnt[i]) tot++,s[i]=tot;
27     int d=ksm(2,n-tot);
28     scanf("%d",&x);
29     for (int i=31;i>=0;i--)
30       if (((x>>i)&1)&&s[i]) ans=((ll)ans+(1<<s[i]-1))%mod;
31     ans=(ll)ans*d%mod;
32     printf("%d\n",(ans+1)%mod);
33    return 0;
34 }

 

题解:线性基

用映射可证每一个可能被异或出的值出现2^(n-线性基元素个数),最后乘一下即可。

在线性基中进行消元,那么每一位的1只有可能在线性基的一个位置上。异或出一个数相当于在位置上增加1。

询问的x若能用s1^s2^s3^...^sk表示,那么可以用:不取最高位,其他任取;取最高位,第二位不取,其他任取;取最高位第二位,不取第三位,其他任取,……这样统计出能够异或出的互不相同的<x的值有多少个。也就是对于该位在x中是1且存在的每一个线性基统计。

posted on 2018-04-04 11:09  Scx117  阅读(94)  评论(0编辑  收藏  举报