Lightoj1267 Points in Rectangle (II)(排序+樹狀數組)

題意

二維平面上給出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;
}
發佈了304 篇原創文章 · 獲贊 7 · 訪問量 11萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章