线段树求调悬关
查看原帖
线段树求调悬关
381926
_Anonymous_楼主2023/3/19 09:02

样例没调过,蒟蒻已经炸了,悬关感谢,请大佬爆踩

#include<bits/stdc++.h>
#define debug cout << "OK" << endl;
#define MAXN int(1e5 + 10)
#define MAXM int(1e6 + 10)
using namespace std;

int n, m;
int a[MAXN];
long long tree[MAXN << 2][20], mark[MAXN << 2];

inline int lson(const int &rt)
{
	return rt << 1;
}

inline int rson(const int &rt)
{
	return rt << 1 | 1;
}

inline void push_up_sum(const int &rt)
{
	for(int i = 0; i < 20; i++)
	{
		tree[rt][i] = tree[lson(rt)][i] + tree[rson(rt)][i];
	}
}

inline void push_down(const int &rt, const int &l, const int &r)
{
	int mid = (l + r) >> 1;
	for(int i = 0; i < 20; i++)
	{
		if((mark[rt] >> i) & 1)//区间取反 
		{
			tree[lson(rt)][i] = (mid - l + 1) - tree[lson(rt)][i];
			tree[rson(rt)][i] = (r - mid) - tree[rson(rt)][i];
		}
	}
	mark[lson(rt)] ^= mark[rt];
	mark[rson(rt)] ^= mark[rt];
	mark[rt] = 0;//清空标记 
}

inline void build(const int &rt, const int &l, const int &r)
{
	if(l == r)
	{
		for(int i = 0; i < 20; i++)
		{
			tree[rt][i] = (a[l] >> i) & 1;
		}
		return ;
	}
	int mid = (l + r) >> 1;
	build(lson(rt), l, mid);
	build(rson(rt), mid + 1, r);
	push_up_sum(rt);
}

inline void update(const int &l, const int &r, const int &rt, const int &cl, const int &cr, const int &d)
{
	if(cl > r || cr < l)
	{
		return ;
	}
	else if(cl <= l && cr >= r)
	{
		for(int i = 0; i < 20; i++)
		{
			if((d >> i) & 1)//区间取反 
			{
				tree[rt][i] = (r - l + 1) - tree[rt][i];
			}
		}
		mark[rt] ^= d;
		return ;
	}
	else
	{
		push_down(rt, l, r);
		update(l, (l + r) >> 1, lson(rt), cl, cr, d);
		update(1 + (l + r) >> 1, r, rson(rt), cl, cr, d);
		push_up_sum(rt);
		return ;
	}
}

inline long long query(const int &l, const int &r, const int &rt, const int &cl, const int &cr)
{
	if(l > cr || r < cl)
	{
		return 0;
	}
	else if(cl <= l && cr >= r)
	{
		long long ans = 0, base = 1;
		for(int i = 0; i < 20; i++)
		{
			ans += base * tree[rt][i];
			base <<= 1;
		}
		return ans;
	}
	else
	{
		push_down(rt, l, r);
		return query(l, (l + r) >> 1, lson(rt), cl, cr) + query(1 + (l + r) >> 1, r, rson(rt), cl, cr);
	}
}

int main()
{
	cin >> n;
	for(int i = 1; i <= n; i++)
	{
		scanf("%d", a + i);
	}
	build(1, 1, n);
	cin >> m;
	while(m--)
	{
		int x, l, r, d;
		scanf("%d %d %d", &x, &l, &r);
		if(x == 1)
		{
			printf("%lld\n", query(1, n, 1, l, r));
		}
		else
		{
			scanf("%d", &d);
			update(1, n, 1, l, r, d);
		}
	}
 	return 0;
}

2023/3/19 09:02
加载中...