在正式的结论推导之前,先由以下的例子进行举例:
然而一不小心默认成了所有线性基都存在,导致误判出了
Q
Q
Q 之前正好有
Q
Q
Q 个数(即
0
0
0 到
Q
−
1
Q-1
Q−1 )的错误结论,于是第一发喜提
70
70
70 分。AC 代码还需要往下翻
70分(未判 Q 之前有多少个数)代码
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N=105;
const int mod=10086;
int p[N];
int ksm(int a,int k){
int res=1;
while(k){
if(k&1) res=res*a%mod;
a=a*a%mod;
k/=2;
}
return res;
}
void insert(int x){
for(int i=60;i+1;i--){
if(!(x>>i))
continue;
if(!p[i]){
p[i]=x;
break;
}
x^=p[i];
}
}
signed main(){
int n;
cin>>n;
int a;
for(int i=1;i<=n;i++){
cin>>a;
insert(a);
}
int cnt=0;
for(int i=60;i+1;i--){
if(p[i])
cnt++;//统计线性基的个数
}
cnt=ksm(2,n-cnt);
//cout<<cnt;
cin>>a;
cout<<((a*cnt)+1)%mod;
return 0;
}
/*
5
6 2 5 4 7
3
*/
吸取教训之后,重新遍历所有的线性基判断 Q Q Q 之前存在的数的个数
AC参考
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N=105;
const int mod=10086;
int p[N];
vector<int> ans;
int ksm(int a,int k){
int res=1;
while(k){
if(k&1) res=res*a%mod;
a=a*a%mod;
k/=2;
}
return res;
}
void insert(int x){
for(int i=60;i+1;i--){
if(!(x>>i))
continue;
if(!p[i]){
p[i]=x;
break;
}
x^=p[i];
}
}
signed main(){
int n;
cin>>n;
int a;
for(int i=1;i<=n;i++){
cin>>a;
insert(a);
}
for(int i=0;i<=60;i++)
if(p[i])
ans.push_back(i);
int cnt=ksm(2,n-ans.size());
cin>>a;
int sum=0;
for(int i=0;i<ans.size();i++){
if(a>>ans[i]&1)
sum+=1<<i;
}
cout<<((sum*cnt)+1)%mod;
return 0;
}
/*
5
6 2 5 4 7
3
*/