P3901 数列找不同(简单莫队)

莫队入门题目,区间不相同数查询

应该用线段树也能做,但是不知道该维护什么。

一篇很好的题解:

https://www.cnblogs.com/MisakaAzusa/p/8684319.html

莫队算法主要解决的问题:

莫队算法是用来处理一类无修改的离线区间询问问题。

莫队算法的思想:

1、分块and排序,使相邻的查询区间尽量接近,curL和curR两个指针移动的距离尽量少

2、桶排查询

代码:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const int maxn=1e5+5;
 5 
 6 int n,m,blo;
 7 int Ans=0,curL,curR,cnt[maxn];
 8 //the initial values of curL and curR both are 0
 9 struct node{
10     int l,r,q;
11 }Q[maxn];
12 int a[maxn];
13 int ans[maxn];
14 
15 bool cmp(node x,node y){
16     return (x.l/blo)==(y.l/blo) ? x.r<y.r : x.l<y.l;
17 }
18 
19 void add(int pos){
20     if((++cnt[a[pos]])==1) ++Ans;
21 }
22 
23 void del(int pos){
24     if((--cnt[a[pos]])==0) --Ans;
25 }
26 
27 
28 int main(){
29     cin>>n>>m;blo=sqrt(n);
30     for(int i=1;i<=n;i++)
31         cin>>a[i];
32     for(int i=1;i<=m;i++){
33         cin>>Q[i].l>>Q[i].r;
34         Q[i].q=i;    
35     }
36     
37     sort(Q+1,Q+1+m,cmp);
38     
39      for(int i=1;i<=m;i++){
40         int L=Q[i].l;int R=Q[i].r;
41         while(curL<L) del(curL++);
42         while(curL>L) add(--curL);
43         while(curR<R) add(++curR);
44         while(curR>R) del(curR--);
45         if(Ans==(R-L+1))
46             ans[Q[i].q]=1; 
47     }
48 
49     for(int i=1;i<=m;i++)
50     {
51         if(ans[i]==1) cout <<"Yes\n";
52             else cout <<"No\n";
53     }
54     return 0;
55 }

 

posted @ 2019-09-05 15:38  Chuhanjing  阅读(157)  评论(0编辑  收藏  举报