题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6483
题目大意:
n个数,m次询问,问是否L到R中最小值到最大值之间是否全部的数都出现过。
只要统计区间不同数字的个数是否等于max-min+1就可以了,不过需要离散化。莫队裸题。
不知道为什么用莫队奇偶优化过不去,普通的莫队就可以过。
辣鸡小编勘误:在鑫爹的英明指导下,发现自己懂了奇偶优化之后太激动了,瞎捷豹打奇偶优化少打个return,该打,该打。
奇偶优化牛逼,鑫爹牛逼。奇偶优化大概省了100ms。
代码:
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int MAXN=1e5+5;
int b[MAXN],a[MAXN];
int n,m,ans[MAXN],C[MAXN],unit;
int mm[MAXN], f[MAXN][20][2];
void st_prework()
{
for(int i = 1; i <= n; i ++) f[i][0][0] = f[i][0][1] = a[i];
int t = log(n) / log(2) + 1;
for(int j = 1; j < t; j ++){
for(int i = 1; i <= n - (1 << j) + 1; i ++){
f[i][j][0] = min(f[i][j - 1][0], f[i + (1 << (j - 1))][j - 1][0]);
f[i][j][1] = max(f[i][j - 1][1], f[i + (1 << (j - 1))][j - 1][1]);
}
}
}
int fmin(int l, int r)
{
int k = log(r - l + 1)/log(2);
return min(f[l][k][0], f[r - (1 << k) + 1][k][0]);
}
int fmax(int l, int r)
{
int k = log(r - l + 1)/log(2);
return max(f[l][k][1], f[r - (1 << k) + 1][k][1]);
}
inline bool scan_d(int &num)
{
char in;bool IsN=false;
in=getchar();
if(in==EOF) return false;
while(in!='-'&&(in<'0'||in>'9')) in=getchar();
if(in=='-'){ IsN=true;num=0;}
else num=in-'0';
while(in=getchar(),in>='0'&&in<='9'){
num*=10,num+=in-'0';
}
if(IsN) num=-num;
return true;
}
struct Query
{
int L,R,id;
int Max,Min;
}node[MAXN];
int k;
int aa(int x)
{
return lower_bound(a+1,a+1+k,x)-a;
}
bool cmp(Query a,Query b)
{
if(a.L/unit!=b.L/unit)return a.L<b.L;
if((a.L/unit)&1) return a.R>b.R;
else return a.R<b.R;
}
void work()
{
int temp=0;
int L=1,R=0;
for(int i=1;i<=m;i++){
while(R<node[i].R){
R++;
if(mm[C[R]]==0)temp++;
mm[C[R]]++;
}
while(R>node[i].R){
if(mm[C[R]]==1)temp--;
mm[C[R]]--;
R--;
}
while(L<node[i].L){
if(mm[C[L]]==1)temp--;
mm[C[L]]--;
L++;
}
while(L>node[i].L){
L--;
if(mm[C[L]]==0)temp++;
mm[C[L]]++;
}
if(temp==node[i].Max-node[i].Min+1)
ans[node[i].id]=1;
else ans[node[i].id]=0;
}
}
int main()
{
int t;
scan_d(t);
while(t--)
{
memset(mm,0,sizeof(mm));
scan_d(n);scan_d(m);
unit=sqrt(n);
for(int i=1;i<=n;i++){
scan_d(C[i]);
a[i]=C[i];
}
st_prework();
sort(a+1,a+1+n);
k=unique(a+1,a+1+n)-a-1;
for(int i=1;i<=n;i++){
C[i]=lower_bound(a+1,a+1+k,C[i])-a;
}
for(int i=1;i<=m;i++){
scan_d(node[i].L);scan_d(node[i].R);
node[i].id=i;
node[i].Max=fmax(node[i].L,node[i].R);
node[i].Min=fmin(node[i].L,node[i].R);
}
sort(node+1,node+1+m,cmp);
work();
for(int i=1;i<=m;i++){
if(ans[i])puts("YES");
else puts("NO");
}
}
}