HDU 4866 Shooting 题解:主席树

来源:互联网 发布:广州城市职业学院网络 编辑:程序博客网 时间:2024/06/07 07:12

这题的主要的坑点就是他给你的射击目标有重合的部分,如果你向这些重合的部分射击的话要考虑两种情况:

射击目标数量 ≥ 重合数量 : 全加上

射击目标数量 ≤ 重合数量 : 只加距离*射击目标数量

然而这题的内存还是很良心的,总体比较水吧。


主要做法是按照横坐标1~x建立主席树,每棵主席树维护l,r区间的设计目标数量,以及这些数量如果全部被射击获得的分数,这些在建树的时候是很好维护的。

然后对这些线段的处理要用扫描线的思想,就(左端点)建立一个(+1)的入点,(右端点+1)的位置建立一个(-1)的出点,然后从左往右扫一遍即可。


具体过程见代码:


#include <stdio.h>#include <string.h>#include <iostream>#include <algorithm>#include <vector>#include <queue>#include <set>#include <map>#include <string>#include <math.h>#include <stdlib.h>#include <time.h>#define INF 2*0x3f3f3f3fusing namespace std;int n, m, x, p;struct N { int ls, rs, w; long long sum; } tree[6000100];int roots[200010];int b[200010], tot, cnt;int build_tree(int l, int r) {    int newnode = tot++;    tree[newnode].w = 0;    tree[newnode].sum = 0;    if (l != r) {        int mid = (l + r) / 2;        tree[newnode].ls = build_tree(l, mid);        tree[newnode].rs = build_tree(mid + 1, r);    }    return newnode;}int updata(int rt, int pos, int val) {    int newnode = tot++, tmp = newnode;    long long add = b[pos - 1];    tree[newnode].sum = tree[rt].sum + add * val;    tree[newnode].w = tree[rt].w + val;    int l = 1, r = cnt;    while (l < r) {        int mid = (l + r) / 2;        if (pos <= mid) {            tree[newnode].ls = tot++;            tree[newnode].rs = tree[rt].rs;            newnode = tree[newnode].ls;            rt = tree[rt].ls;            r = mid;        }        else {            tree[newnode].ls = tree[rt].ls;            tree[newnode].rs = tot++;            newnode = tree[newnode].rs;            rt = tree[rt].rs;            l = mid + 1;        }        tree[newnode].sum = tree[rt].sum + add * val;        tree[newnode].w = tree[rt].w + val;    }    return tmp;}long long query(int rt, int k) {    //printf("rt = %d k = %d\n",rt,k);    int l = 1, r = cnt;    long long ans = 0;    while (l < r) {        int mid = (l + r) / 2;        int tmp = tree[tree[rt].ls].w;        if (tmp >= k) {            rt = tree[rt].ls;            r = mid;        }        else {            k -= tmp;            ans += tree[tree[rt].ls].sum;            rt = tree[rt].rs;            l = mid + 1;        }    }    if (tree[rt].w != 0)        ans += tree[rt].sum / tree[rt].w * min(k, tree[rt].w);    return ans;}struct P {    int x, y, val;    P() {}    P(int _x, int _y, int _val) : x(_x), y(_y), val(_val) {}    bool operator < (const P &rhs) const {        return x < rhs.x;    }} pois[500010];void print(int rt, int l = 1, int r = cnt) {    printf("l = %d r = %d w = %d sum = %I64d\n", l, r, tree[rt].w, tree[rt].sum);    if (l != r) {        int mid = (l + r) / 2;        print(tree[rt].ls, l, mid);        print(tree[rt].rs, mid + 1, r);    }}int main() {    //freopen("in.in", "r", stdin);    //freopen("out.out", "w", stdout);    while (scanf("%d %d %d %d", &n, &m, &x, &p) != EOF) {        int l1, l2, d;        int ps = 0;        for (int i = 0; i < n; i++) {            scanf("%d %d %d", &l1, &l2, &d);            b[i] = d;            pois[ps++] = P(l1, d, 1);            pois[ps++] = P(l2 + 1, d, -1);        }        sort(b, b + n);        cnt = unique(b, b + n) - b;        sort(pois, pois + ps);        tot = 0;        roots[0] = build_tree(1, cnt);        int t = 0;        for (int i = 1; i <= x; i++) {            roots[i] = roots[i - 1];            while (t < ps && pois[t].x == i) {                int tmp = (int)(lower_bound(b, b + cnt, pois[t].y) - b) + 1;                roots[i] = updata(roots[i], tmp, pois[t].val);                t++;            }        }        /*        for (int i = 1; i <= x; i++) {            printf("**********************tree %d is : \n", i);            print(roots[i]);        }        */        long long now = 1;        int xs, as, bs, cs;        for (int i = 0; i < m; i++) {            //printf("i = %d\n", i);            scanf("%d %d %d %d", &xs, &as, &bs, &cs);            long long tmp = query(roots[xs], (now * as + bs) % cs);            if (now > p) tmp *= 2;            printf("%I64d\n", tmp);            now = tmp;        }}return 0;}


0 0