数论(好题)

给你一个数组a,求ans=(a1+a2)^ (a1+a3)^ …(a n-1+a n),(共(n+1)*n/2项),数组长度是10的5次方,ai是10的7次方的,求ans。

解析:一位一位的算。一堆0和1异或的结果,只和其中的1的个数有关,与0个个数无关。

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <iostream>
#include <iomanip>
#include <string>
#include <algorithm>
#include <stack>
#include <queue>
#include <set>
#include <vector>
#include <map>

#define INF 0x3f3f3f3f
#define LINF 0x3f3f3f3f3f3f3f3f
#define ll long long
#define ull unsigned long long
#define uint unsigned int
#define l(x) ((x)<<1)
#define r(x) ((x)<<1|1)
#define lowbit(x) ((x)&(-(x)))
#define ms(a,b) memset(a,b,sizeof(a))
#define NSYNC std::ios::sync_with_stdio(false);std::cin.tie(0);std::cout.tie(0);

using namespace std;

const int N = 17000000;
int n, a[400009], t1[N + 9], t2[N + 9];

void add(int*t, int x) {
	for (; x <= N; x += lowbit(x))
		t[x] += 1;
}
int sum(int*t, int x) {
	int r = 0;
	for (; x; x -= lowbit(x)) 
		r += t[x];
	return r;
}
int main() {
	int i, j, k, p, q, s = 0;
	long long u;

	scanf("%d", &n);
	for (i = 1; i <= n; ++i)
		scanf("%d", a + i);

	for (i = 1 << 24; i; i >>= 1) {
		u = p = q = 0;
		memset(t1, 0, sizeof(t1));
		memset(t2, 0, sizeof(t2));

		for (j = 1; j <= n; ++j) {
			k = a[j] & (i - 1);
			if (a[j] & i) {
				u += p - sum(t1, i - k) + sum(t2, i - k);
				add(t1, k + 1), ++p;
			}
			else {
				u += q - sum(t2, i - k) + sum(t1, i - k);
				add(t2, k + 1), ++q;
			}
		}

		if (u & 1)
			s |= i;
	}
	printf("%d", s);

	return 0;
}
发布了86 篇原创文章 · 获赞 8 · 访问量 2216

猜你喜欢

转载自blog.csdn.net/Fawkess/article/details/104771947