对莫队左端点的设置的问题
查看原帖
对莫队左端点的设置的问题
730828
UMS2楼主2024/8/2 11:24

先上代码。

#include<bits/stdc++.h>
#define int long long
using namespace std;

const int N=6e4+5,inf=1e18;
int n,m,blo,res;
int ori[N],bkt[(1<<26)+5],ans[N],bel[N];

struct Ques{
	int l,r,id;
	
	bool operator <(const Ques x)const{
		if(bel[l]^bel[x.l])return bel[l]<bel[x.l];
		return (bel[l]&1)^(r>x.r);
	}
}q[N];

void add(int x){
	res+=bkt[ori[x]];
	for(int i=0;i<26;i++)res+=bkt[ori[x]^(1<<i)];
	bkt[ori[x]]++;
}

void del(int x){
	bkt[ori[x]]--;
	res-=bkt[ori[x]];
	for(int i=0;i<26;i++)res-=bkt[ori[x]^(1<<i)];
}

signed main(){
	ios::sync_with_stdio(0);
	cin>>n>>m;
	blo=n/sqrt(m);
	char x;
	for(int i=1;i<=n;i++){
		cin>>x;
		ori[i]=1<<(x-'a');
		ori[i]^=ori[i-1];
		bel[i]=(i-1)/blo+1;
	}
	
	for(int i=1,l,r;i<=m;i++){
		cin>>l>>r;
		q[i]=(Ques){l-1,r,i};
	}
	sort(q+1,q+m+1);
	for(int i=1,l=1,r=0,nl,nr;i<=m;i++){//这里
		nl=q[i].l,nr=q[i].r;
		while(l>nl)add(--l);
		while(r<nr)add(++r);
		while(l<nl)del(l++);
		while(r>nr)del(r--);
		
		ans[q[i].id]=res;
	}
	for(int i=1;i<=m;i++)cout<<ans[i]<<endl;
	return 0;
}

莫队的左端点在这里是 11,改成 00 就会 WA。 但在本题的弱化版[https://www.luogu.com.cn/problem/P4462](P4462 [CQOI2018] 异或序列) 中,莫队左端点设为 00 是对的,设为 11 是错误的。

#include<bits/stdc++.h>
#define int long long
using namespace std;

const int N=2e5+5,inf=1e18;
int n,m,k,blo,res;
int ori[N],bkt[N],ans[N],bel[N];

struct Ques{
	int l,r,id;
	
	bool operator <(const Ques x)const{
		if(bel[l]^bel[x.l])return bel[l]<bel[x.l];
		return (bel[l]&1)^(r>x.r);
	}
}q[N];

void add(int x){
	res+=bkt[ori[x]^k];
	bkt[ori[x]]++;
}

void del(int x){
	bkt[ori[x]]--;
	res-=bkt[ori[x]^k];
}

signed main(){
	ios::sync_with_stdio(0);
	cin>>n>>m>>k;
	blo=n/sqrt(m);
	for(int i=1;i<=n;i++){
		cin>>ori[i];
		ori[i]^=ori[i-1];
		bel[i]=(i-1)/blo+1;
	}
	
	for(int i=1,l,r;i<=m;i++){
		cin>>l>>r;
		q[i]=(Ques){l-1,r,i};
	}
	sort(q+1,q+m+1);
	bkt[0]=1;
	for(int i=1,l=0,r=0,nl,nr;i<=m;i++){
		nl=q[i].l,nr=q[i].r;
		while(l>nl)add(--l);
		while(r<nr)add(++r);
		while(l<nl)del(l++);
		while(r>nr)del(r--);
		ans[q[i].id]=res;
	}
	for(int i=1;i<=m;i++)cout<<ans[i]<<endl;
	return 0;
}

这是为啥?

2024/8/2 11:24
加载中...