CodeForces - 369E Valera and Queries(树状数组)

来源:互联网 发布:上海口腔网络咨询招聘 编辑:程序博客网 时间:2024/05/11 01:19

题目大意:给出N条线段,有M个询问,询问的内容是,k个点,共落在多少条所给线段上

解题思路:这次参考了一下别人的题解。首先,很难直接从正面判断落在几条线段上,因为线段是会重叠的,且,有可能有多个点落在同一条线段上的
既然正面难以思考的话,那就用反面,判断一下有多少条所给线段会被不包含所有点的线段给包含在内,假设所给的点是1,4,7,那就判断[2,3],[5,6],[8,Max-1]这三个线段,共包含多少条所给线段,只要被包含在内,那么所给的点必然不会落在所给线段上,所以最后只需要用N-包含的线段即可
现在的问题是统计一下线段了。首先,先处理出所有的不包含线段,还要给每个线段打上标记,看是属于哪个问题的
接着将所给线段和处理出来的线段排个序,最容易被包含的先处理,最容易被包含的,就是那些l比较大,r比较小的
然后树状数组维护的是前缀和,表示的是到该点,有多少条线段被包含里面
因为排序的时候是l大的先处理,所以后续的线段的l都会小于等于前面的线段的,所以依此处理是可以的

#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int N = 1000010;const int M = 300010;struct Node {    int l, r, id;    Node() {}    Node(int l, int r, int id): l(l), r(r), id(id){}}node[N];int bit[N], ans[M];int n, m;inline int lowbit(int x) {    return x & (-x);}void Modify(int x) {    while (x < N) {        bit[x]++;        x += lowbit(x);    }}int Query(int x) {    int ans = 0;    while (x) {        ans += bit[x];        x -= lowbit(x);    }    return ans;}int cmp(const Node &a, const Node &b) {    if (a.l == b.l) {        if (a.r == b.r) return a.id < b.id;        return a.r < b.r;    }    return a.l > b.l;}void solve() {    memset(ans, 0, sizeof(ans));    memset(bit, 0, sizeof(bit));    for (int i = 1; i <= n; i++) {        scanf("%d%d", &node[i].l, &node[i].r);        node[i].id = 0;    }    int cnt = n;    int num, p1, p2;    for (int i = 1; i <= m; i++) {        scanf("%d%d", &num, &p1);        if (p1 > 1) node[++cnt] = Node(1, p1 - 1, i);        p2 = p1;        for (int j = 2; j <= num; j++) {            scanf("%d", &p2);            if (p1 + 1 <= p2 - 1) node[++cnt] = Node(p1 + 1, p2 - 1, i);            p1 = p2;        }        node[++cnt] = Node(p2 + 1, N - 7, i);    }    sort(node + 1, node + 1 + cnt, cmp);    for (int i = 1; i <= cnt; i++) {        if (node[i].id) ans[node[i].id] += Query(node[i].r);        else Modify(node[i].r);    }    for (int i = 1; i <= m; i++)        printf("%d\n", n - ans[i]);}int main() {    while (scanf("%d%d", &n, &m) != EOF) solve();    return 0;}
0 0
原创粉丝点击