找不同大战
查看原帖
找不同大战
800499
suzhikz楼主2025/1/13 15:53

题解

#include<bits/stdc++.h>
#define ll long long
#define reg register
#define db double
#define il inline
using namespace std;
void read(int &x){x=0;int f=1;char c=getchar();while(c>'9'||c<'0'){if(c=='-')f=-1;c=getchar();}while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}x*=f;}
void read(ll &x){x=0;int f=1;char c=getchar();while(c>'9'||c<'0'){if(c=='-')f=-1;c=getchar();}while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}x*=f;}
const int N=2e5+5;
int n,q,a[N];
struct node{
	int minn,mncnt,se,cnt[35],tag,summ;
}tree[N<<2];
void push_up(int x){
	int ls=x<<1,rs=x<<1|1;
	tree[x].summ=tree[ls].summ^tree[rs].summ;
	for(int i=0;i<30;i++){tree[x].cnt[i]=tree[ls].cnt[i]+tree[rs].cnt[i];}
	if(tree[ls].minn<tree[rs].minn){
		tree[x].minn=tree[ls].minn;
		tree[x].se=min(tree[ls].se,tree[rs].minn);
		tree[x].mncnt=tree[ls].mncnt;		
	}else if(tree[ls].minn>tree[rs].minn){
		swap(ls,rs);tree[x].minn=tree[ls].minn;
		tree[x].se=min(tree[ls].se,tree[rs].minn);
		tree[x].mncnt=tree[ls].mncnt;swap(ls,rs);
	}else{
		tree[x].minn=tree[ls].minn;tree[x].mncnt=tree[ls].mncnt+tree[rs].mncnt;
		tree[x].se=min(tree[ls].se,tree[rs].se);
	}
}
void build(int x,int l,int r){
	tree[x].tag=-1;
	if(l==r){
		tree[x].minn=tree[x].summ=a[l];tree[x].se=((1ll<<35)+1);tree[x].mncnt=1;
		for(int i=0;i<30;i++){
			if((1<<i)&a[l])tree[x].cnt[i]=1;
		}
		return;
	}
	int mid=(l+r)/2;
	build(x<<1,l,mid);build(x<<1|1,mid+1,r);
	push_up(x);
}
void set_tag(int x,int v){
	if(tree[x].minn>=v)return;
	tree[x].summ=tree[x].summ^((tree[x].mncnt&1)*(tree[x].minn^v));
	for(int i=0;i<30;i++){
		if(tree[x].minn&(1<<i))tree[x].cnt[i]-=tree[x].mncnt;
		if(v&(1<<i))tree[x].cnt[i]+=tree[x].mncnt;
	}
	tree[x].minn=v;tree[x].tag=v;
}
void push_down(int x){
	if(tree[x].tag==-1)return;
	set_tag(x<<1,tree[x].tag);set_tag(x<<1|1,tree[x].tag);tree[x].tag=-1;
}
int query1(int x,int l,int r,int ql,int qr){
	if(ql<=l&&qr>=r)return tree[x].summ;
	push_down(x);
	int re=0,mid=(l+r)/2;
	if(ql<=mid)re=query1(x<<1,l,mid,ql,qr);
	if(qr>mid)re^=query1(x<<1|1,mid+1,r,ql,qr);
	return re;
}
int query2(int x,int l,int r,int ql,int qr,int v){
	if(ql<=l&&qr>=r){
		return tree[x].cnt[v];
	}
	push_down(x);
	int re=0,mid=(l+r)/2;
	if(ql<=mid)re=query2(x<<1,l,mid,ql,qr,v);
	if(qr>mid)re+=query2(x<<1|1,mid+1,r,ql,qr,v);
	return re;
}
void update(int x,int l,int r,int ql,int qr,int v){
	if(tree[x].minn>=v)return;
	if(ql<=l&&qr>=r&&tree[x].se>v){//
		set_tag(x,v);return;
	}
	push_down(x);
	int mid=(l+r)/2;
	if(ql<=mid)update(x<<1,l,mid,ql,qr,v);
	if(qr>mid)update(x<<1|1,mid+1,r,ql,qr,v);
	push_up(x);
}
signed main(){
//	freopen("my.in","r",stdin);
	read(n);read(q);
	for(int i=1;i<=n;i++)read(a[i]);
	build(1,1,n);
	int op,l,r,x;
	while(q--){
		read(op);read(l);read(r);read(x);
		if(op==1){
			update(1,1,n,l,r,x);
		}else{
			int tmp=query1(1,1,n,l,r);tmp^=x;
			if(!tmp)puts("0");
			else for(int i=29;i>=0;i--){
				if(tmp&(1<<i)){
					printf("%d\n",query2(1,1,n,l,r,i)+(x&(1<<i)));break;
				}
			}
		}
	}
	return 0;
}

2025/1/13 15:53
加载中...