P11071 「QMSOI R1」 Distorted Fate

题目链接

简要题意:

给定一个长度为 \(n\) 的数组 \(A\),你需要完成以下 \(q\) 次操作。

  1. 1 l r x\(A_i(l\le i\le r)\) 异或上 \(x\)

  2. 2 l r 求:

\[(\sum_{i=l}^r\bigcup_{j=l}^i A_j) \bmod 2^{30} \]

其中 \(\bigcup\) 表示按位或。
区间异或,查询区间每个前缀的按位或之和的和

主要算法:

按位计算,线段树,优化空间。

思路:

  1. 因为是二进制相关的计数,所以自然想到拆位来做。
  2. 拆完位之后,区间异或就是0,1翻转,统计答案就是找到 \(l\)\(r\) 中第一个一所在的位置。只有0,1,所以线段树维护一的个数即可。
#include <bits/stdc++.h>
using namespace std;
const int mod=(1<<30),N=2e5+10;
#define int long long//注意long long
int n,q,a[N];
long long ans[N];
struct node
{
	int opt,l,r,x;
}qq[N];
struct stu
{
	int sum,tag;
}sh[N<<2];
inline void build(int x,int l,int r,int k)
{
	sh[x].tag=0;//全部清空 
	if(l==r)
	{
		if((a[l]>>k)&1)sh[x].sum=1;
		else sh[x].sum=0;
		sh[x].tag=0;
		return ; 
	}
	int mid=(l+r)>>1;
	build(x<<1,l,mid,k);build(x<<1|1,mid+1,r,k);
	sh[x].sum=sh[x<<1].sum+sh[x<<1|1].sum;
	return ;
} 
void pushdown(int x,int l,int r)
{
	if(sh[x].tag==0)return;
	int mid=(l+r)>>1;
	sh[x<<1].sum=(mid-l+1)-sh[x<<1].sum;
	sh[x<<1].tag^=1;
	sh[x<<1|1].sum=(r-mid)-sh[x<<1|1].sum;
	sh[x<<1|1].tag^=1;
	sh[x].tag=0;	
}
inline void modify(int x,int l,int r,int lt,int rt,int zhi)
{
	if(zhi==0)return;
	if(l>rt||r<lt)return;
	if(lt<=l&&rt>=r)
	{
		sh[x].sum=(r-l+1)-sh[x].sum;
		sh[x].tag^=1;
		return ;
	}
	pushdown(x,l,r);
	int mid=(l+r)>>1;
	if(lt<=mid)modify(x<<1,l,mid,lt,rt,zhi);
	if(rt>mid)modify(x<<1|1,mid+1,r,lt,rt,zhi);
	sh[x].sum=sh[x<<1].sum+sh[x<<1|1].sum;
	return ; 
}
inline int query(int x,int l,int r)
{
 	if(!sh[x].sum)return -1;
	if(l==r) return sh[x].sum?l:-1;
	pushdown(x,l,r);
	int mid=(l+r)>>1;
	int q2=query(x<<1,l,mid);
	if(q2!=-1)return q2; 
	q2=query(x<<1|1,mid+1,r);
	if(q2!=-1)return q2;
	return -1; 
}//不能只写这一部分,不然找的就是全局最大。
inline int query2(int x,int l,int r,int lt,int rt)
{
	if(lt<=l&&rt>=r)
	{
		int q2=query(x,l,r);
		if(q2!=-1)return q2;
		else return -1;
	}
	int mid=(l+r)>>1,q2=-1;
	pushdown(x,l,r);
	if(lt<=mid)q2=query2(x<<1,l,mid,lt,rt);
	if(q2!=-1)return q2; 
	if(rt>mid)q2=query2(x<<1|1,mid+1,r,lt,rt);
	if(q2!=-1)return q2;
	return -1;
}
signed main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);cout.tie(0);
	cin>>n>>q;
	for(int i=1;i<=n;i++)cin>>a[i];
	for(int i=1;i<=q;i++)
	{
		cin>>qq[i].opt>>qq[i].l>>qq[i].r;
		if(qq[i].opt==1)
			cin>>qq[i].x;
	}
	long long anw;
	for(int i=0,anw=1;i<=30;i++,anw*=2)
	{
		build(1,1,n,i);
		for(int j=1;j<=q;j++)//注意i,j 
		{
			if(qq[j].opt==1)	
				modify(1,1,n,qq[j].l,qq[j].r,(qq[j].x>>i)&1);//右移左移要注意 
			else
			{
				int q2=query2(1,1,n,qq[j].l,qq[j].r);
				if(q2!=-1)
				ans[j]=(ans[j]+anw*(qq[j].r-q2+1)%mod)%mod;
			}	
		}
	}
	for(int i=1;i<=q;i++)
	{
		if(qq[i].opt==2)cout<<ans[i]<<'\n'; 
	}
	return 0;
}
posted @ 2024-10-08 17:02  storms11  阅读(4)  评论(0编辑  收藏  举报