noip模拟赛?#16T3

题目大意:不告诉你QAQ

直接搬题解辣

对于位运算的题目,我们都可以把数拆成二进制,一位一位分开来考虑。那么我们只需要考虑0,1串的情况。我们枚举每一位作为连续段末端点R

对于or:如果这一位为0,那么我们需要找到前面最近的一个1,L在这之前的(L,R)的结果都是1,其它都是0,统计入答案;

如果这一位为1,那么所有的(L,R)结果都是1,直接计入答案。

对于and:如果这一位为0,结果都是0,答案直接不加。
如果这一位为1,我们找之前最近的0,L在这之后的(L,R)的结果为1,其它为0,统计入答案。

对于xor,我们需要知道之前xor完答案为0的(L,R-1)有几个,答案为1的(L,R-1)有几个,知道之后我们也可以统计答案。

而找最近的1,最近的0,以及之前xor完答案为0,1的有几个,这些我们可以在扫描过程中得到答案,所以做一遍是O(N),

我们做31遍即可得出每一位上的答案,就算出最终答案了。

注意:本题设定L>R也是有意义的,写的时候要注意这一点。

竟然不同调就A了(赛后QAQ)

爽!!!

#include
#include
const int N=1e5+7;
int a[N];
int main()
{
	freopen("nine.in","r",stdin);
	freopen("nine.out","w",stdout);
	int n;
	scanf("%d",&n);
	for(int i=1;i<=n;i++)	scanf("%d",&a[i]);
	long long sum1=0,sum2=0,sum3=0;
	int qu1=0,qu0=0;
	int ans1=0,ans0=0;
	for(int i=0;i<=30;i++)
	{
		int kkk=(1<


你可能感兴趣的:(————二进制运算———)