位运算简单例题

题目链接:http://oj.daimayuan.top/course/22/problem/899​​​​​​

 方法:常规思路为记录每一个数字出现的次数,然后再选出只出现一次的数,最后进行排序输出。但是这里不行,因为数据范围很大。所以我想到位运算。

xor的性质:a^a=0,两个相同的数进行异或,则会消为0,结合题意,我们将数组中的每一个数进行xor,最后会得到一个值M,然而出现偶数个的数,最终通过xor都消为了0,所以M=a^b。a,b分别为最后只出现一次的两个数。

代码:

#include<bits/stdc++.h>
using namespace std;
const int N=2e6+10;
int a[N];

int main(){
	int n;cin>>n;
	for(int i=1;i<=n;i++) cin>>a[i];
	int v=0;
	for(int i=1;i<=n;i++) v^=a[i];
	int c=0;
	while(v){//找最高位1的位置:从右往左
		c++;v>>=1;
	}
	int minn=0,maxx=0;
	for(int i=1;i<=n;i++){
		if((a[i]>>(c-1))&1) maxx^=a[i];
//最高位的1,一定是最后两个数中的较大值,依次xor,因为其他数会出现两次,所以最终只会剩下较大值
		else minn^=a[i];//同理
	}
	cout<<minn<<" "<<maxx;
}

题目链接:http://oj.daimayuan.top/course/22/problem/948

 

 题意:j&i=j,说明j是i的子集(想想&的性质)。其次是j<i,说明j是i的子集,但其中的子集是不等于i的。(因为i本身也是i的子集)

方法:理解题意后,书写公式即可

代码:

#include<bits/stdc++.h>
using namespace std;
const int N=2e6+10;
const int mod=1e9+7;
int n,f[N];

int main(){
	cin>>n;f[0]=1;
	for(int i=1;i<1<<n;i++){
		f[i]=1;
		for(int j=(i-1)&i;j;j=(j-1)&i){//枚举子集
			f[i]+=f[j];f[i]%=mod;//书写题目公式
		}
		f[i]=1LL*f[i]*i%mod;//书写题目公式
	}
	for(int i=0;i<1<<n;i++) cout<<f[i]<<" ";
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值