【离散化 && 线段树 && 染色】POJ - 2528 Mayor's posters
2017-08-23 21:56
429 查看
Problem Description
给你T组测试数据,每组测试数据输入n,代表有n行,接下来每行输入ul, ur代表海报贴的区间覆盖是ul-ur。问你贴完后能看到多少张海报。
Sample Input
1
5
1 4
2 6
8 10
3 4
7 10
Sample Output
4
思路:
因为给你的海报贴的区间范围有点大,如果直接开线段树肯定爆内存。所以我们先离散化一下,因为1<=n<=10000,所以最多有2*n个不同的点。我们就将区间压缩,如果压缩呢?例如样例:我们将所有点排序取重得到
1 2 3 4 6 7 8 10 让它们分别对应1 2 3 4 5 6 7 8这样最大原本是10,压缩到了8。区间1->4, 2->6, 8->10, 3->4, 7->10对应就变为1->4, 2->5, 7->8, 3->4, 6->8。这样的结果得到的结果是不会改变的。接下来就是如何处理贴海报,我们倒着贴题目就变得非常简单了,判断区间是否贴满,没有贴满ans++。贴满了,你在贴也就是被覆盖了。
给你T组测试数据,每组测试数据输入n,代表有n行,接下来每行输入ul, ur代表海报贴的区间覆盖是ul-ur。问你贴完后能看到多少张海报。
Sample Input
1
5
1 4
2 6
8 10
3 4
7 10
Sample Output
4
思路:
因为给你的海报贴的区间范围有点大,如果直接开线段树肯定爆内存。所以我们先离散化一下,因为1<=n<=10000,所以最多有2*n个不同的点。我们就将区间压缩,如果压缩呢?例如样例:我们将所有点排序取重得到
1 2 3 4 6 7 8 10 让它们分别对应1 2 3 4 5 6 7 8这样最大原本是10,压缩到了8。区间1->4, 2->6, 8->10, 3->4, 7->10对应就变为1->4, 2->5, 7->8, 3->4, 6->8。这样的结果得到的结果是不会改变的。接下来就是如何处理贴海报,我们倒着贴题目就变得非常简单了,判断区间是否贴满,没有贴满ans++。贴满了,你在贴也就是被覆盖了。
#include<cstdio> #include<algorithm> using namespace std; #define lson root << 1 #define rson root << 1 | 1 #define MID int mid = (l + r) / 2 #define N 20005 struct node { int lazy; int sum;//没贴过的地方为0,贴过的为1 }; node tree[4 * N]; int a [2], data[2 * N]; node merge_(node x, node y) { node t; t.lazy = 0; t.sum = x.sum + y.sum; return t; } void build(int root, int l, int r) { tree[root].lazy = 0; if(l == r) { tree[root].sum = 0; return; } MID; build(lson, l, mid); build(rson, mid + 1, r); tree[root] = merge_(tree[lson], tree[rson]); } void pushdown(int root, int l, int r) { if(tree[root].lazy) { MID; tree[lson].lazy = tree[rson].lazy = tree[root].lazy; tree[lson].sum = (mid - l + 1) * tree[lson].lazy; tree[rson].sum = (r - (mid + 1) + 1) * tree[rson].lazy; tree[root].lazy = 0; } } int query(int root, int l, int r, int ul, int ur)//求区间ul-ur的和 { if(ul <= l && r <= ur) { return tree[root].sum; } pushdown(root, l, r); int red = 0; MID; if(ul <= mid) red += query(lson, l, mid, ul, ur); if(ur > mid) red += query(rson, mid + 1, r, ul, ur); return red; } void updata(int root, int l, int r, int ul, int ur, int v)//更新ul-ur的区间为1 { if(ul <= l && r <= ur) { tree[root].lazy = v; tree[root].sum = (r - l + 1) * v; return; } pushdown(root, l, r); MID; if(ul <= mid) updata(lson, l, mid, ul, ur, v); if(ur > mid) updata(rson, mid + 1, r, ul, ur, v); tree[root] = merge_(tree[lson], tree[rson]); } int main() { int T, n, i; scanf("%d", &T); while(T--) { scanf("%d", &n); int top = 1; for(i = 1; i <= n; i++) { scanf("%d %d", &a[i][0], &a[i][1]);//将点存起来 data[top++] = a[i][0]; data[top++] = a[i][1]; } sort(data + 1, data + top);//排序 top = unique(data + 1, data + top) - data;//去重 build(1, 1, top);//初始化建树 int cnt = 0; for(i = n; i >= 0; i--) { int ul = lower_bound(data + 1, data + top, a[i][0]) - data;//取离散化后的左区间 int ur = lower_bound(data + 1, data + top, a[i][1]) - data;//取离散化后的右区间 int ans = query(1, 1, top, ul, ur); if(ans != ur - ul + 1) cnt++;//代表区间ul-ur没有贴满 updata(1, 1, top, ul, ur, 1);//更新 } printf("%d\n", cnt); } }
相关文章推荐
- (重温)poj 2528 Mayor's posters 线段树 染色+离散化
- POJ 2528 Mayor's posters 离散化和线段树题解
- poj 2528 Mayor's posters 【线段树 + 离散化】
- POJ 2528 Mayor's posters 离散化+线段树
- POJ 2528 Mayor's posters 线段树成段更新+离散化
- POJ 2528 Mayor's posters 线段树和离散化
- poj 2528 Mayor's posters【离散化+线段树】
- poj 2528 Mayor's posters 【线段树 + 离散化】
- POJ 2528 Mayor's posters 离散化+线段树
- POJ 2528 Mayor's posters 线段树的区间覆盖 离散化
- Mayor's posters----POJ_2528----线段树之成段更新and离散化
- Poj 2528 Mayor's posters 线段树 离散化 成段更新
- POJ-2528-Mayor's posters【线段树 & 离散化】
- POJ 2528 Mayor's posters(线段树染色+离散化)
- POJ 2528-Mayor's posters(线段树区间染色+离散化)
- poj 2528 Mayor's posters(线段树,离散化,成段更新染色)
- POJ 2528 Mayor's posters // 线段树 区间更新 离散化
- poj 2528 Mayor's posters(线段树+离散化)
- poj 2528 Mayor's posters 线段树
- POJ 题目2528 Mayor's posters(线段树+离散化)