【福建省赛】Bilibili(线段树 单点更新,成段查询)

来源:互联网 发布:showgirl是什么软件 编辑:程序博客网 时间:2024/06/04 19:09

思路:线段树,sum存放的是这个区间每一行可用的最小的最终时间,更新的时候把该点更新为每行的长度加弹幕的长度再加出现的时间即可。

简单的线段树,省赛当初没学线段树,不会。

现在回头一做,1A

#define _CRT_SECURE_NO_WARNINGS#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;#define MAX 50005#define ls rt<<1#define rs ls|1#define m (l+r)>>1int sum[MAX << 2];void uprt(int rt){sum[rt] = min(sum[ls], sum[rs]);}void updata(int q, int c, int l, int r, int rt){if (l == r){sum[rt] = c;return;}int mid = m;if (q <= mid)updata(q, c, l, mid, ls);elseupdata(q, c, mid + 1, r, rs);uprt(rt);}int query(int q, int l, int r, int rt){if (l == r)return l;int mid = m;if (sum[ls] <= q)return query(q, l, mid, ls);return query(q, mid + 1, r, rs);}void build(int l, int r, int rt){if (l == r){sum[rt] = 0;return;}int mid = m;build(l, mid, ls);build(mid + 1, r, rs);uprt(rt);}int main(){int t;cin >> t;int icase = 1;while (t--){int n, k, q;scanf("%d%d%d", &n, &k, &q);build(1, n, 1);int a, b,cur;printf("Case #%d:\n", icase++);while (q--){scanf("%d%d", &a, &b);if (sum[1] > a){printf("Failed!\n");continue;}cur = query(a, 1, n, 1);updata(cur, a + k + b, 1, n, 1);printf("%d\n", cur);}}}


0 0