您的位置:首页 > 其它

【BZOJ1293】【SCOI2009】生日礼物

2018-02-27 10:02 435 查看
【题目链接】
点击打开链接

【思路要点】
对于一个左端点\(i\),设最小的合法右端点为\(F_i\)。
显然,\(F_i\)是单调不减的,用Two Pointers计算可能的\(F_i\)即可。
时间复杂度\(O(NLogN)\)。
【代码】
#include<bits/stdc++.h>
using namespace std;
#define MAXN	1000005
#define INF	2100000000
#define MAXK	105
struct info {int pos, type; };
info a[MAXN];
bool cmp(info x, info y) {return x.pos<y.pos; }
int main() {
int n, k;
scanf("%d%d", &n, &k);
int tot = 0;
for (int i = 1; i <= k; i++) {
int sum;
scanf("%d", &sum);
for (int j = 1; j <= sum; j++) {
int tmp;
scanf("%d", &tmp);
a[++tot] = (info){tmp, i};
}
}
sort(a+1, a+n+1, cmp);
int now = 1, cnt = 0, ans = INF;
static int mark[MAXK];
for (int i = 1; i <= n; i++) {
while (now <= n && cnt<k) {
if (mark[a[now].type] == 0) cnt++;
mark[a[now].type]++;
now++;
}
if (cnt == k) ans = min(ans, a[now-1].pos-a[i].pos);
if (mark[a[i].type] == 1) cnt--;
mark[a[i].type]--;
}
printf("%d\n", ans);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: