[luoguP2564] [SCOI2009]生日礼物(队列)

传送门

不停的枚举 l ,然后枚举长度,直到所有颜色都包含,这是 n2 做法,超时。

仔细想想,可以用个队列来维护。

还是枚举 l ,用队列来维护当前区间的包含所有颜色,l 增加时再判断。

——代码

 1 # include <iostream>
 2 # include <cstdio>
 3 # include <cstring>
 4 # include <string>
 5 # include <cmath>
 6 # include <vector>
 7 # include <map>
 8 # include <queue>
 9 # include <cstdlib>
10 # include <algorithm>
11 # define MAXN 1000001
12 using namespace std;
13 
14 inline int get_num() {
15     int k = 0, f = 1;
16     char c = getchar();
17     for(; !isdigit(c); c = getchar()) if(c == '-') f = -1;
18     for(; isdigit(c); c = getchar()) k = k * 10 + c - '0';
19     return k * f;
20 }
21 
22 int n, k, tot, sum, h, t, ans = 1 << 30;
23 int num[MAXN];
24 
25 struct node
26 {
27     int a, pos;
28 }p[MAXN];
29 
30 inline bool cmp(node x, node y)
31 {
32     return x.pos < y.pos;
33 }
34 
35 int main()
36 {
37     int i, j, m;
38     n = get_num();
39     k = get_num();
40     for(i = 1; i <= k; i++)
41         for(j = 1, m = get_num(); j <= m; j++)
42             p[++tot].a = i, p[tot].pos = get_num();
43     sort(p + 1, p + n + 1, cmp);
44     for(h = 1, t = 0; h <= n; h++)
45     {
46         while(sum < k && t < n)
47         {
48             if(!num[p[++t].a]) sum++;
49             num[p[t].a]++;
50         }
51         if(sum == k) ans = min(ans, p[t].pos - p[h].pos);
52         num[p[h].a]--;
53         if(!num[p[h].a]) sum--;
54     }
55     printf("%d", ans);
56     return 0;
57 }
View Code
原文地址:https://www.cnblogs.com/zhenghaotian/p/6830512.html