根据所求更改 add,del,answer就好
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define bug(x) cout<<#x<<" == "<<x<<endl;
const int maxn = 3e3+5;
ll mod = 1e6+7;
///const ll int INF=0x3f;
int a[maxn] = { 0 };
int block = 1;
inline int belong(int x)///也可以直接利用一个数组预处理下
{
return (x-1)/block+1;
///x属于哪一块
}
int ans = 0;///当前区间有多少个元素
int cnt[100005] = { 0 };///目前区间的每个元素的个数统计
struct node
{
int l,r;
int id;
bool operator <(node a)
{
if(belong(l)==belong(a.l))
{
return r<a.r;///属于同一块时 按右端点从小到大排序
}
else
{
return l<a.l;
}
}
}pp[maxn];
string answer[maxn];///最后要输出的答案
inline void add(int pos)
{
cnt[ a[pos] ]++;
if(cnt[ a[pos] ]==1)
ans++;
}
inline void del(int pos)
{
cnt[ a[pos] ]--;
if(cnt[ a[pos] ]==0)
ans--;
}
int main()
{
int n,p;
scanf("%d %d",&n,&p);
int gs = (int)sqrt(n*1.0)+1;
block = ceil(n/gs);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
for(int i=1;i<=p;i++)
{
scanf("%d %d", &pp[i].l,&pp[i].r);
pp[i].id = i;
}
sort(pp+1,pp+1+p);
int l=1,r=0;
///初始区间 是0
for(int i=1;i<=p;i++)
{
int nl=pp[i].l;
int nr=pp[i].r;
///下一个区间
while(nl<l)
{
l--;
add(l);
}
while(r<nr)
{
r++;
add(r);
}///扩大区间
while(nl>l)
{
del(l);
l++;
}
while(r>nr)
{
del(r);
r--;
}///缩小区间
if( ans == (nr-nl+1) )
answer[ pp[i].id ]="Yes\n";
else
answer[ pp[i].id ]="No\n";
}
for(int i=1;i<=p;i++)
cout<<answer[i];
}
异或思想的运用很不错
链接;https://www.luogu.com.cn/problem/P4462
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define bug(x) cout<<#x<<" == "<<x<<endl;
const int maxn = 5e5+5;
ll mod = 1e6+7;
///const ll int INF=0x3f;
int a[maxn] = { 0 };
int block = 1;
inline int belong(int x)///也可以直接利用一个数组预处理下
{
return (x-1)/block+1;
///x属于哪一块
}
ll ans = 0;
ll cnt[maxn] = { 0 };///每种颜色的袜子的个数的统计
ll answer[maxn] = { 0 };
struct node
{
int l,r;
int id;
bool operator <(node a)
{
if(belong(l)==belong(a.l))
{
return r<a.r;///属于同一块时 按右端点从小到大排序
}
else
{
return l<a.l;
}
}
}pp[maxn];
int k;
inline void add(int pos)
{
cnt[ a[pos] ]++;
ans += cnt[ a[pos]^k ];///(a^b)^b = a;-> (a^k)^a = k;
}
inline void del(int pos)
{
ans -= cnt[ a[pos]^k ];
cnt[ a[pos] ]--;
}
int main()
{
int n,p;
scanf("%d %d %d", &n, &p, &k);
int gs = (int)sqrt(n*1.0)+1;
block = ceil(n/gs);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
a[i] = a[i-1]^a[i];///转换为在区间[l,r]有多少对数异或为k
///a[l] ^ a[r]=(a[1]^a[2]^...^a[l])^(a[1]^a[2]^...^a[l])^(a[l+1]^a[l+2]^...^a[r])
///=(a[l+1]^a[l+2]^...^a[r])
}
for(int i=1;i<=p;i++)
{
scanf("%d %d", &pp[i].l,&pp[i].r);
pp[i].id = i;
pp[i].l--;
///a[i]记录的是从1~i的前缀异或
///所以区间[l,r]转化为的前缀异或区间应该是[l-1,r];
}
sort(pp+1,pp+1+p);
int l=1,r=0;
///初始区间 是0
for(int i=1;i<=p;i++)
{
int nl=pp[i].l;
int nr=pp[i].r;
///下一个区间
while(nl<l)
{
l--;
add(l);
}
while(r<nr)
{
r++;
add(r);
}///扩大区间
while(nl>l)
{
del(l);
l++;
}
while(r>nr)
{
del(r);
r--;
}///缩小区间
answer[ pp[i].id ] = ans;
}
for(int i=1;i<=p;i++)
{
printf("%lld\n",answer[i]);
}
}