您的位置:首页 > 其它

LightOj1089(求点包含几个线段 + 线段树)

2016-03-08 23:43 309 查看
题目链接

题意:n( n <= 50000 ) 个线段,q ( q <= 50000) 个点,问每个点在几个线段上

线段端点的和询问的点的值都很大,所以必须离散化

第一种解法:先把所有的线段端点和询问点,离散处理,然后对于每条选段处理,c[x]++, c[y + 1]--,然后令c[x] = c[x] + c[x - 1],所以c[x]就保存了被几个线段覆盖,然后对对于每个询问点,查找他在离散后的位置,然后直接读取c[],这种方法很巧妙,佩服佩服

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
using namespace std;
const int Max = 50000 + 10;
struct node
{
int l,r;
int tag,cnt;
};
node tree[4 * Max];
int a[4 * Max], b[4 * Max], c[4 * Max], querry[Max];
int tot;
void buildTree(int left, int right, int k)
{
tree[k].l = left;
tree[k].r = right;
tree[k].tag = -1;
tree[k].cnt = 0;
if(left == right)
return;
int mid = (left + right) / 2;
buildTree(left, mid, k * 2);
buildTree(mid + 1, right, k * 2 + 1);
}
void upDate(int left, int right, int k, int newp)
{
if(tree[k].tag != -1)
{
tree[k * 2].tag = tree[k * 2 + 1].tag = tree[k].tag;
tree[k * 2].cnt++;
tree[k * 2 + 1].cnt++;
tree[k].tag = -1;
}
if(tree[k].l == left && tree[k].r == right)
{
tree[k].cnt++;
tree[k].tag = newp;
return;
}
int mid = (tree[k].l + tree[k].r) / 2;
if(right <= mid)
upDate(left, right, k * 2, newp);
else if(mid < left)
upDate(left, right, k * 2 + 1, newp);
else
{
upDate(left, mid, k * 2, newp);
upDate(mid + 1, right, k * 2 + 1, newp);
}
}
int Search(int k, int value)
{
if(tree[k].l == tree[k].r)
return tree[k].cnt;
if(tree[k].tag != -1)
{
tree[k * 2].tag = tree[k * 2 + 1].tag = tree[k].tag;
tree[k * 2].cnt++;
tree[k * 2 + 1].cnt++;
tree[k].tag = -1;
}

int mid = (tree[k].l + tree[k].r) / 2;
if(value <= mid)
return Search(k * 2, value);
else
return Search(k * 2 + 1, value);
}
int main()
{
int test, n, q;
scanf("%d", &test);
for(int t = 1; t <= test; t++)
{
scanf("%d%d", &n, &q);
tot = 0;
for(int i = 1; i <= n; i++)
{
scanf("%d%d", &a[i], &b[i]);
c[tot++] = a[i];
c[tot++] = b[i];
}
for(int i = 1; i <= q; i++)
{
scanf("%d", &querry[i]);
c[tot++] = querry[i];
}
sort(c, c + tot);
tot = unique(c, c + tot) - c;
buildTree(1, tot, 1);
for(int i = 1; i <= n; i++)
{
int x = lower_bound(c, c + tot, a[i]) - c + 1;
int y = lower_bound(c, c + tot, b[i]) - c + 1;
upDate(x, y, 1, 1);
}
printf("Case %d:\n", t);
for(int i = 1; i <= q; i++)
{
int x = lower_bound(c, c + tot, querry[i]) - c + 1;
printf("%d\n", Search(1, x));
}
}
return 0;
}


未AC
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: