ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

洛谷 P4869 albus就是要第一个出场(线性基)

2021-10-28 18:00:52  阅读:132  来源: 互联网

标签:P4869 洛谷 int res 异或 return include albus mod


传送门


解题思路

首先背过线性基的一个性质吧(因为我不会证明):
线性基里的每一个异或值出现的次数相等,为 \(2^{n-k}\) 。
然后这题就变成统计某个数是第几大异或值了。
分类讨论在归纳一下:
假设询问的数字是q。当处理到第i位且q的这一位为1,且线性基这一位有数,则

  • 当前面位异或起来得到的这一位已经是1,则可以通过让其他数异或上a[i]来减小其他数,使其小于q。
  • 当前面位异或起来得到的这一位是0,则q必须要异或上a[i],但是别的数可以通过不异或a[i]使其小于q。

综上,第i位对答案是否产生贡献只与q的第i位原来是否为1有关,与现在的状态无关。

AC代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<vector>
using namespace std;
const int mod=10086;
int n,x,a[35],cnt,q,ans[35];
int ksm(int a,int b){
	if(b==0) return 1;
	if(b==1) return a;
	int res=ksm(a,b/2);
	if(b&1) return res*res%mod*a%mod;
	return res*res%mod;
}
void insert(int x){
	for(int i=30;i>=0;i--){
		if(x&(1<<i)){
			if(a[i]) x^=a[i];
			else{
				a[i]=x;
				return;
			}
		}
	}
}
int query(int x){
	int res=0;
	for(int i=30;i>=0;i--){
		if((x&(1<<i))&&(a[i])){
			res=(res+ksm(2,ans[i]))%mod;
		}
	}
	return res;
}
int main(){
	ios::sync_with_stdio(false);
	cin>>n;
	for(int i=1;i<=n;i++) cin>>x,insert(x);
	for(int i=0;i<=30;i++) if(a[i]) ans[i]=cnt++;
	cin>>q;
	cout<<(ksm(2,n-cnt)*query(q)+1)%mod;
	return 0;
}

标签:P4869,洛谷,int,res,异或,return,include,albus,mod
来源: https://www.cnblogs.com/yinyuqin/p/15476568.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有