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 }