poj 2464(区间更新)

来源:互联网 发布:网络喷子到底是哪些人 编辑:程序博客网 时间:2024/06/08 22:41

题意:给出n个点的坐标,Stan和Ollie玩游戏,Stan会先选一个点过这个点画一条竖直的线,然后Ollie会在这条竖直的线上过一个点画一条横线,然后平面分成了四部分,Stan会将第一和第三象限上的点的数量作为自己的分数,Ollie会将第二和第四象限上的点的数量作为自己的分数,线上的点不计,Stan会采用让自己最小分数最大的方案去选择画竖线,Ollie会选择让自己分数更多的方案划线,要求输出Stan的最大的最小分数,然后输出在这种情况下的所有Ollie的分数,按升序排列。
题解:这题其实用树状数组写会更好,但是这里用了线段树,思路来自这位http://blog.csdn.net/shiqi_614/article/details/8236745,分别用两个线段树tree1和tree2维护Stan和Ollie的分数,把y坐标离散化,然后按x坐标从小到大排序,把每个y的上方有多少个点和下方有多少个点都统计并作为线段树初始值,然后从最左边的点开始扫描,所有x相同的点,用修改函数要把这些点从两个树内删除,因为线上的点不计,然后查询这些点的值更新结果,然后把这些点再加入线段树方便下一个x的查询。

#include <cstdio>#include <cstring>#include <algorithm>#include <map>#include <vector>using namespace std;const int N = 200005;const int INF = 0x3f3f3f3f;struct Point {    int x, y;    bool operator < (const Point &a) const { return x < a.x; }}p[N];int n, tree1[N << 2], tree2[N << 2], numh[N], numl[N], res1;vector<int> a, b, res2;map<int, int> mp;void pushdown(int k) {    tree1[k * 2] += tree1[k];    tree1[k * 2 + 1] += tree1[k];    tree2[k * 2] += tree2[k];    tree2[k * 2 + 1] += tree2[k];    tree1[k] = tree2[k] = 0;}void build(int k, int left, int right) {    tree1[k] = tree2[k] = 0;    if (left == right) {        tree1[k] = numh[left];        tree2[k] = numl[left];        return;    }    int mid = (left + right) / 2;    build(k * 2, left, mid);    build(k * 2 + 1, mid + 1, right);}void modify(int k, int left, int right, int l, int r, int flag, int v) {    if (l <= left && right <= r) {        if (flag == 1) tree1[k] += v;        else tree2[k] += v;        return;    }    pushdown(k);    int mid = (left + right) / 2;    if (l <= mid)        modify(k * 2, left, mid, l, r, flag, v);    if (r > mid)        modify(k * 2 + 1, mid + 1, right, l, r, flag, v);}void query(int k, int left, int right, int pos, int& temp1, int& temp2) {    if (left == right) {        temp1 = tree1[k];        temp2 = tree2[k];        return;    }    pushdown(k);    int mid = (left + right) / 2;    if (pos <= mid)        query(k * 2, left, mid, pos, temp1, temp2);    else        query(k * 2 + 1, mid + 1, right, pos, temp1, temp2);}int main() {    while (scanf("%d", &n) == 1 && n) {        a.clear(), b.clear(), mp.clear(), res2.clear();        for (int i = 0; i < n; i++) {            scanf("%d%d", &p[i].x, &p[i].y);            a.push_back(p[i].y);        }        sort(p, p + n);        sort(a.begin(), a.end());        b.push_back(a[0]);        int m = 0;        numl[m] = 0;        mp[a[0]] = 0;        for (int i = 0; i < n; i++) {            if (b[m] != a[i]) {                numh[m] = n - i;                numl[++m] = i;                b.push_back(a[i]);                mp[b[m]] = m;            }        }        numh[m] = 0;        build(1, 0, m);        res1 = 0;        for (int cur1 = 0; cur1 < n;) {            int cur2 = cur1;            while (cur2 < n && p[cur1].x == p[cur2].x) {                if (p[cur2].y != b[0])                    modify(1, 0, m, mp[b[0]], mp[p[cur2].y] - 1, 1, -1);                if (p[cur2].y != b[m])                    modify(1, 0, m, mp[p[cur2].y] + 1, mp[b[m]], 2, -1);                cur2++;            }            int maxx = 0, minn = INF;            for (int i = cur1; i < cur2; i++) {                int temp1, temp2;                query(1, 0, m, mp[p[i].y], temp1, temp2);                minn = min(minn, temp1);                maxx = max(maxx, temp2);            }            if (minn == res1)                res2.push_back(maxx);            else if (minn > res1) {                res1 = minn;                res2.clear();                res2.push_back(maxx);            }            for (int i = cur1; i < cur2; i++) {                if (p[i].y != b[0])                    modify(1, 0, m, mp[b[0]], mp[p[i].y] - 1, 2, 1);                if (p[i].y != b[m])                    modify(1, 0, m, mp[p[i].y] + 1, mp[b[m]], 1, 1);            }            cur1 = cur2;        }        sort(res2.begin(), res2.end());        res2.erase(unique(res2.begin(), res2.end()), res2.end());        printf("Stan: %d; Ollie:", res1);        int sz = res2.size();        for (int i = 0; i < sz; i++)            printf(" %d", res2[i]);        printf(";\n");    }    return 0;}
0 0
原创粉丝点击