Cookie Choice II
Problem Description
As all you know, MM loves cookies very much and now she’s going to make another cookie choice!
There is a sequence of N cookies while there may be K different kinds of cookies.
MM wants to choose a continuous subsequence of cookies to eat (the subsequence may be empty), while for each kind of cookie, there are minimum and maximum numbers MM want to choose.
But DD wants to minimize the length of chosen continuous subsequence (for his poor wallet). You are to find the shortest continuous sequences that satisfy MM’s requirement.
Formally speaking, define the cookie sequence as C i C_i Ci ( 1 < = i < = N , 1 < = C i < = K 1<=i<=N, 1<=C_i<=K 1<=i<=N,1<=Ci<=K), where C i C_i Ci is the kind of the ithe cookie, and the chosen continuous subsequence has Mi cookies of kind i. Mi must satisfy A i < = M i < = B i A_i<=M_i<=B_i Ai<=Mi<=Bi. While A i A_i Ai and B i B_i Bi are given miminum and maximum numbers of kind i to choose.
Input
About 20 test cases, seperated by blank line.
First line of each case is two integers N N N ( 1 < = N < = 400000 1<=N<=400000 1<=N<=400000) and K K K ( 1 < = K < 2048 1<=K<2048 1<=K<2048). The second line is N numbers of sequence C. The following K lines, the ith line has two numbers A i A_i Ai and B i B_i Bi.
All numbers are integers.
Output
For each test case, output the minimum length of chosen continuous subsequence.
If no answer, output -1.
Sample Input
5 2
1 2 2 2 1
2 4
1 3
7 2
1 2 1 2 1 2 1
3 4
0 1
Sample Output
5
-1
题意
有一个包含n个数的序列,序列中的每个数都是 [ 1 , k ] ( 1 ≤ k ≤ 2048 ) [1,k](1\le k\le2048) [1,k](1≤k≤2048)的数字。要求选出一段连续的子序列,使 [ 1 , k ] [1,k] [1,k]中的每个数字出现的次数 n u m i num_i numi满足 a i ≤ n u m i ≤ b i a_i \le num_i \le b_i ai≤numi≤bi。求满足条件的最短子序列的长度。
题解:
尺取法。每次数字出现的次数需要满足上界和下界,所有的子序列都必须达到下界,所以在尺取时找到满足下界的最短长度。同时在统计出现次数时,记录有多少个数超出了上界。如果有超出上界的话,则该段区间不成立。
ai貌似可以为负数。
#include<stdio.h>
#include<iostream>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<map>
#include<vector>
#include<queue>
#include<iterator>
#define dbg(x) cout<<#x<<" = "<<x<<endl;
#define INF 0x3f3f3f3f
#define eps 1e-6
using namespace std;
typedef long long LL;
typedef pair<int, int> P;
const int maxn = 500100;
const int mod = 1000000007;
int a[maxn], b[3000], c[3000], d[3000];
int main()
{
int n, k, i, j, l, r, num1, num2, sig;
while(scanf("%d %d", &n, &k)!=EOF)
{
memset(d, 0, sizeof(d));
num1 = num2 = sig = 0;
int ans = INF;
for(i=0;i<n;i++)
scanf("%d", &a[i]);
for(i=1;i<=k;i++){
scanf("%d %d", &b[i], &c[i]);
//貌似b[i]可能为负数,改为b[i]==0会WA
if(b[i] <= 0)num1++;
}
if( num1 == k){
printf("0\n");
continue;
}
l = 0, r = 0;
while(l<n){
while(r<n && num1<k){
j = a[r];
d[j]++;
if(d[j] == b[j])num1++;
if(d[j] == c[j]+1)num2++;
r++;
}
if(num1 == k && num2 == 0)ans = min(ans, r-l);
j = a[l];
if(d[j] == b[j])num1--;
if(d[j] == c[j]+1)num2--;
d[j]--;
l++;
}
if(ans == INF)printf("-1\n");
else printf("%d\n", ans);
}
return 0;
}