洛谷 P3901 数列找不同

洛谷 P3901 数列找不同

 

题目描述

现有数列 A1,A2,,AN ,Q 个询问 (Li,Ri) , ALi,ALi+1,,ARi 是否互不相同

 

输入格式:

 

第1 行,2 个整数 N,Q

第2 行,N 个整数 ALi,ALi+1,,ARi

Q 行,每行2 个整数 Li,Ri

 

输出格式:

 

对每个询问输出一行,“Yes” 或者“No”

 

 

输入样例#1: 
4 2
1 2 3 2
1 3
2 4
输出样例#1: 
Yes
No

说明

• 对于50% 的数据, N,Q103

• 对于100% 的数据, 1N,Q105,1AiN,1LiRiN

 

题解:

此题为水题一枚,暴力+预处理直接过,做作的我用了莫队~V~

其实一看就是莫队模板题,只不过要一个小小的转化思考。

判断一段数是否互不相同其实就只要记录下这一段内不同数的个数 sum,如果 sum== r-l+1 那么就说明这一段数是互不相同的。

废话不多说,上代码:

 

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int N=100005;
 4 int n,m,a[N],block,belong[N],sum,num[N];
 5 string ans[N];
 6 struct node{
 7     int l,r,id;
 8 }q[N];
 9 inline int read()
10 {
11     int x=0,f=1; char ch=getchar();
12     while (!isdigit(ch))
13       f=(ch=='-')?-f:f,ch=getchar();
14     while (isdigit(ch))
15       x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
16     return x*f;
17 }
18 bool cmp(node a,node b)
19 {
20     return belong[a.l]==belong[b.l]?(belong[a.r]==belong[b.r]?a.id<b.id:a.r<b.r):a.l<b.l;
21 }
22 void revise(int x,int w)
23 {
24     num[a[x]]+=w;
25     if (w>0) sum+=(num[a[x]]==1);
26     if (w<0) sum-=(num[a[x]]==0);
27 }
28 int main()
29 {
30     n=read(),m=read(); block=sqrt(n);
31     for (int i=1; i<=n; i++)
32     {
33         a[i]=read(); belong[i]=i/block+1;
34     }
35     for (int i=1; i<=m; i++)
36     {
37         q[i].l=read(),q[i].r=read(),q[i].id=i;
38     }
39     sort(q+1,q+1+m,cmp);
40     int zl=1,zr=0; sum=0;
41     memset(num,0,sizeof(num));
42     for (int i=1; i<=m; i++)
43     {
44         while (zl<q[i].l) revise(zl,-1),zl++;
45         while (zl>q[i].l) revise(zl-1,1),zl--;
46         while (zr<q[i].r) revise(zr+1,1),zr++;
47         while (zr>q[i].r) revise(zr,-1),zr--;
48         if (sum==zr-zl+1) ans[q[i].id]="Yes";
49         else ans[q[i].id]="No";
50     }
51     for (int i=1; i<=m; i++)
52       cout<<ans[i]<<endl;
53     return 0;
54 }
View Code

 

 

加油加油加油!!! fighting fighting fighting !!!

posted on 2018-06-11 21:00  Frank-King  阅读(116)  评论(0编辑  收藏  举报