One day, WNJXYK found a very hard problem on an Online Judge. This problem is so hard that he had been thinking about the solutions for a couple of days. And then he had a surprise that he misunderstood that problem and easily figured out a solution using segment tree. Now he still wonders that solution for the misread problem.
There is a sequence with N positive integers A1,A2,…,An and M queries. Each query will give you an interval [L,R] and require an answer with YES/NO indicates that whether the numbers in this interval are continuous in its integer range.
Let us assume that the maximal number in an interval is mx and the minimal number is mi. The numbers in this interval are continuous in its integer range means that each number from mi to mx appears at least once in this interval.
Input
The input starts with one line contains exactly one positive integer T which is the number of test cases. And then there are T cases follow.
The first line contains two positive integers n,m which has been explained above.The second line contains positive integers A1,A2,…,An.
Then there will be m lines followed. Each line contains to positive numbers Li,Ri indicating that the ith query’s interval is [Li,Ri].
Output
For each test case, output m line.
Each of following m lines contains a single string “YES”/ “NO” which is the answer you have got.
Sample Input
2
3 3
3 1 2
2 3
1 3
1 2
5 3
1 2 2 4 5
1 5
1 3
3 3
Sample Output
YES
YES
NO
NO
YES
YES
Hint
T=5
1<=n<=100000
1<=Ai<=10^9
1<=m<=100000
The input file is very large, so you are recommend to use scanf() and printf() for IO.
题意:
给你一个数组,每次询问你l到r的区间中是否从这个区间的最小值到这个区间的最大值都出现过,是输出YES,否则输出NO:1 2 3 3 就是YES 1 2 2 4就是NO。
题解:
那么这道题就变成了区间不同值的个数>=区间最大值-区间最小值+1。
求区间不同值的个数的时候一开始想用主席树来着,但是它给的空间范围太小了,所以只能以时间换空间,用莫队来做。注意这里不能用unordered_map,因为就算它的时间复杂度也太大了,所以得离散化做。区间查询可以用线段树。
#include<bits/stdc++.h>
using namespace std;
namespace fastIO {
#define BUF_SIZE 100000
//fread -> read
bool IOerror = 0;
inline char nc() {
static char buf[BUF_SIZE], *p1 = buf + BUF_SIZE, *pend = buf + BUF_SIZE;
if(p1 == pend) {
p1 = buf;
pend = buf + fread(buf, 1, BUF_SIZE, stdin);
if(pend == p1) {
IOerror = 1;
return -1;
}
}
return *p1++;
}
inline bool blank(char ch) {
return ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t';
}
inline void read(int &x) {
char ch;
while(blank(ch = nc()));
if(IOerror) return;
for(x = ch - '0'; (ch = nc()) >= '0' && ch <= '9'; x = x * 10 + ch - '0');
}
#undef BUF_SIZE
};
using namespace fastIO;
const int N=1e5+5;
struct node
{
int l,r,id;
}q[N];
int pos[N];
bool cmp(node a,node b)
{
return pos[a.l]<pos[b.l]||pos[a.l]==pos[b.l]&&a.r<b.r;
}
int a[N];
int maxn[N*4],minn[N*4];
void build(int l,int r,int root)
{
if(l==r)
{
maxn[root]=minn[root]=a[l];
return ;
}
int mid=l+r>>1;
build(l,mid,root<<1);
build(mid+1,r,root<<1|1);
maxn[root]=max(maxn[root<<1],maxn[root<<1|1]);
minn[root]=min(minn[root<<1],minn[root<<1|1]);
}
int qmax(int l,int r,int root,int ql,int qr)
{
if(l>=ql&&r<=qr)
return maxn[root];
int mid=l+r>>1;
int mx=0;
if(mid>=ql)
mx=qmax(l,mid,root<<1,ql,qr);
if(mid<qr)
mx=max(mx,qmax(mid+1,r,root<<1|1,ql,qr));
return mx;
}
int qmin(int l,int r,int root,int ql,int qr)
{
if(l>=ql&&r<=qr)
return minn[root];
int mid=l+r>>1;
int mn=1e9;
if(mid>=ql)
mn=qmin(l,mid,root<<1,ql,qr);
if(mid<qr)
mn=min(mn,qmin(mid+1,r,root<<1|1,ql,qr));
return mn;
}
int vis[N],b[N];
int num;
int ans[N];
void add(int pos)
{
if(!vis[a[pos]])
num++;
vis[a[pos]]++;
}
void del(int pos)
{
if(vis[a[pos]]==1)
num--;
vis[a[pos]]--;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
memset(vis,0,sizeof(vis));
int n,qq;
read(n),read(qq);
int blog=sqrt(n);
for(int i=1;i<=n;i++)
pos[i]=(i-1)/blog+1;
for(int i=1;i<=n;i++)
read(a[i]),b[i]=a[i];
sort(b+1,b+1+n);
for(int i=1;i<=n;i++)
a[i]=lower_bound(b+1,b+1+n,a[i])-b;
build(1,n,1);
for(int i=1;i<=qq;i++)
read(q[i].l),read(q[i].r),q[i].id=i;
sort(q+1,q+1+qq,cmp);
num=0;
int l=q[1].l,r=q[1].l-1;
for(int i=1;i<=qq;i++)
{
while(r<q[i].r)
add(++r);
while(l>q[i].l)
add(--l);
while(l<q[i].l)
del(l++);
while(r>q[i].r)
del(r--);
int mx=qmax(1,n,1,q[i].l,q[i].r);
int mn=qmin(1,n,1,q[i].l,q[i].r);
if(mx-mn+1>num)
ans[q[i].id]=0;
else
ans[q[i].id]=1;
}
for(int i=1;i<=qq;i++)
printf("%s\n",ans[i]?"YES":"NO");
for(int i=0;i<n*4;i++)
maxn[i]=0,minn[i]=1e9;
}
return 0;
}