CF1872E-Data Structures Fan

CF1872E-Data Structures Fan

题目大意

给你一个长度为 \(n\) 的序列,每个数字有一个对应的 \(0\)\(1\) 。现在你有 \(q\) 次操作。

\(1\space l\space r\)\(l\)\(r\) 区间内的所有数的 \(0\) , \(1\) 取反。

\(2 \space x\) 统计所有对应数字为 \(x\) 的数的异或和。

题解

对于 \(1\) 操作的维护。我们先将序列求前缀异或和,然后再跟所有数的初始对应值,分类异或和存进 \(xor1,xor0\) 两个变量中。这样每次操作,我们只需要用前缀异或和得到 \(l,r\) 区间内的异或和,对应异或上 \(xor1,xor0\) 就可以完成 \(0,1\) 翻转的操作。

对于 \(2\) 操作的查询,就只要对应输出 \(xor1,xor0\) 的值即可。

#include<bits/stdc++.h>
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define umap unordered_map
#define endl '\n'
using namespace std;
using i128 = __int128;
const int mod =1e9+7;
template <typename T>void read(T&x){
    x=0;int f = 1;
    char c=getchar();
    for(;!isdigit(c);c=getchar())if(c=='-')f=-1;
    for(;isdigit(c);c=getchar())x=(x<<1)+(x<<3)+(c^48);
    x*=f;
}
template <typename T>void print(T x) {
     if (x < 0) { putchar('-'); x = -x; }
     if (x > 9) print(x / 10);
     putchar(x % 10 + '0');
}
#define int long long
const int N=500005;
const int M=2000005;
inline void solve()
{
	int n;
	cin>>n;
	vector<int> num(n+1),sum(n+1);
	for(int i=1;i<=n;i++) cin>>num[i];
	for(int i=1;i<=n;i++) sum[i]=sum[i-1]^num[i];
	int xor1=0,xor0=0;
	string s;
	cin>>s;
	for(int i=0;i<n;i++)
	{
		if(s[i]=='1')
		{
			xor1^=num[i+1];
		}
		else
		{
			xor0^=num[i+1];
		}
	}
	int q;
	cin>>q;
	while(q--)
	{
		int id;
		cin>>id;
		if(id==1)
		{
			int l,r;
			cin>>l>>r;
			xor0^=sum[r]^sum[l-1];
			xor1^=sum[r]^sum[l-1];
		}
		else
		{
			int x;
			cin>>x;
			if(x==0)
			{
				cout<<xor0<<" ";
			}
			else
			{
				cout<<xor1<<" ";
			}
		}
	}
	cout<<endl;
}

signed main()
{
	ios;
	int T=1;
	cin>>T;
	for(;T--;) solve();
	return 0;
}
posted @ 2025-12-01 17:34  NDAKJin  阅读(1)  评论(0)    收藏  举报