题意:
给定长度为n的序列a,m个询问
每个询问:
问区间[l,r]中的数是否是1-(r-l+1)的一个排列(全排列中的一种)
数据范围:n<=1e6,1<=a(i)<=n
解法:
n最大1e6,给1到1e6的每个数随机一个hash值,预处理异或前缀和h_pre[]
然后用前面的hash数组对给定的序列a计算异或前缀和,a_pre[]
如果a_pre[r]^a_pre[l-1]==h_pre[r-l+1],那么说明是排列。
正确性显然,因为[l,r]的异或和等于1到n的异或和,那么肯定是排列。
code:
#include <bits/stdc++.h>
#define ull unsigned long long
using namespace std;
const int maxm=1e6+5;
ull h[maxm];
ull h_pre[maxm];//前缀异或和
int a[maxm];
ull a_pre[maxm];
int n,m;
signed main(){
for(int i=1;i<maxm;i++){
h[i]=rand()*rand();
h_pre[i]=h_pre[i-1]^h[i];
}
while(scanf("%d%d",&n,&m)!=EOF){
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
a_pre[i]=a_pre[i-1]^h[a[i]];
}
while(m--){
int l,r;scanf("%d%d",&l,&r);
if(h_pre[r-l+1]==(a_pre[r]^a_pre[l-1])){
puts("YES");
}else{
puts("NO");
}
}
}
return 0;
}