P1638 逛画展 左右指针移动

这道题不是莫队,只是有莫队的影子

题意:给出n个数字,给出m个画家(表示这n个数字为1~m)

   让我们找到一个最小的范围涵盖这1~m个数,如果多解,则输出左区间最小的解

思路:我们用左右指针移动来做此题,类似于莫队;

    那么如何做呢?我们一开始从第一个端点开始,把第一个端点纳进来,然后开始分情况讨论;

      假如已经涵盖,就看看能否更新答案,然后左指针右移

      假如没涵盖,则右指针右移直到涵盖为止;

复杂度答案2*1e6

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=1e6+10;
 4 const int inf=0x3f3f3f3f;
 5 int a[maxn];
 6 int vis[maxn];
 7 int sum;
 8 void add(int x)
 9 {
10     if(!vis[x]) sum++;
11     vis[x]++;
12 }
13 void Delete(int x)
14 {
15     vis[x]--;
16     if(!vis[x]) sum--;
17 }
18 int main()
19 {
20     int n,m;
21     scanf("%d%d",&n,&m);
22     for(int i=1;i<=n;i++) scanf("%d",&a[i]);
23     int l=1,r=1;
24     add(a[1]);
25     int ansa=inf;
26     int ansb=inf;
27     int len=inf;
28     while(r<=n){
29         if(sum<m){
30             if(r==n) break;
31             r++;
32             add(a[r]);
33         }
34         if(sum==m){
35             int tmp=r-l+1;
36             if(len>tmp){
37                 ansa=l;ansb=r;
38                 len=tmp;
39             }
40             l++;Delete(a[l-1]);
41         }
42     }
43     printf("%d %d\n",ansa,ansb);
44     return 0;
45 }
View Code

 

posted @ 2020-04-06 10:03  古比  阅读(99)  评论(0编辑  收藏  举报