Lightoj1267 Points in Rectangle (II)(排序+树状数组)

来源:互联网 发布:transmac制作mac安装盘 编辑:程序博客网 时间:2024/06/05 10:32

题意

二维平面上给出p个点,然后q次讯问。每次讯问一个矩形内有多少个点落于里面,包涵边界。

思路

容易想到二维树状数组,但是空间炸了。可以降维处理,去掉x这一维。离散化y值,把所有点放在一起排序,每个点还有其编号、离散化后的y值、是否是询问矩形上的点、左下角还是右上角等信息。然后按照x的大小排序,剩下的看代码。
const int MAXN =1e6 + 12;int p, q;struct point {    int x, y;    bool p;    bool st;    int idx, i;    int yy;    int y1, y2;};vector<point> vec;bool cmp1(const point& A, const point& B) {    return A.y < B.y;}bool cmp2(const point& A, const point& B) {    return A.i < B.i;}bool cmp3(const point& A, const point& B) {    if (A.x == B.x) return A.p > B.p;    return A.x < B.x;}struct BIT {    int sum[MAXN];    void init() {memset(sum, 0, sizeof sum);}    void add(int pos, int val) {        while(pos < MAXN) {            sum[pos] += val;            pos += lowbit(pos);        }    }    int Getsum(int pos) {        int res = 0;        while(pos > 0) {            res += sum[pos];            pos -= lowbit(pos);        }        return res;    }}solve;int ans[MAXN];int main(int argc, const char * argv[]){        // freopen("in.txt","r",stdin);    // freopen("out.txt","w",stdout);    int kase;read(kase);    while(kase--) {        read(p), read(q);        point a;        vec.clear();        Rep(i, 0, p - 1) {            scanf("%d%d", &a.x, &a.y);            a.p = true;            a.i = i;            vec.push_back(a);        }        Rep(i, 0, q - 1) {            a.i = p + 2*i;            a.p = false;            a.st = true;            a.idx = i;            scanf("%d%d", &a.x, &a.y);            a.x -= 1;//important            vec.push_back(a);            a.i = p + 2*i + 1;            a.p = false;            a.st = false;            a.idx = i;            scanf("%d%d", &a.x, &a.y);            vec.push_back(a);        }        //离散化        sort(ALL(vec), cmp1);        int num = 1;        vec[0].yy = num;        int size = vec.size();        for (int i = 1;i < size;++i) {            if (vec[i].y != vec[i-1].y) num++;            vec[i].yy = num;        }        //[1, num]        sort(ALL(vec), cmp2);        for (int i = p;i < size;i += 2) {            vec[i].y1 = vec[i].yy;            vec[i].y2 = vec[i+1].yy;            vec[i+1].y1 = vec[i].yy;            vec[i+1].y2 = vec[i+1].yy;        }        solve.init();        //x排序        sort(ALL(vec), cmp3);        for (int i = 0;i < size;++i) {            if (vec[i].p) {                solve.add(vec[i].yy, 1);            }else if (vec[i].st) {                ans[vec[i].idx] = solve.Getsum(vec[i].y2) - solve.Getsum(vec[i].y1 - 1);            }else {                ans[vec[i].idx] = solve.Getsum(vec[i].y2) - solve.Getsum(vec[i].y1 - 1) - ans[vec[i].idx];            }        }        printf("Case %d:\n", ++nCase);        for (int i = 0;i < q;++i)            printf("%d\n", ans[i]);    }    // showtime;    return 0;}
0 0