問題を解決P2163 [[SHOI2007]庭師のトラブル]

トピックリンク

ソリューション[SHOI2007]庭師のトラブル

タイトル効果:指定された\(N- \)ツリー座標に各クエリ((B)\ \ )は、 下端点を残し、\((C、D)は、\)長方形の木の右下端であります数量

効果の対象:通常動作と第1の2次元の接頭辞について:

\(S_ {I、J} \) 左下端点である\((0,0)\) 右上端点()\(i、j)を \の中の木の数

その後、各グループの答えを尋ねます

\(年数= S_ {C、D} - S_ { - 1、D} - S_ {C、B-1} + S_ {-1、B-1} \)

私たちのポイントは、2つのカテゴリに分かれています。お問い合わせ・ポイントとポイントを変更します

各照会点については、我々はその頼む(; X \当量MX \ \と\; Y \当量私\) 2次元部分順序の問題である点の数を、直接プレス\(X \)の並べ替えを、その後は、\(CDQ \)にパーティション

我々は注意する必要があり、その2点のソート順序\(\) \(B \)

場合は\(;および\; AX = BX \ AYによって= \) 私たちは前にポイントを変更する
場合は、\(AX = BX \;と \; \によってAY \のNEQ) 我々はを押し\(のy \)ソート
の場合\(AX \ NEQ BX \)私たちが押して\(X \)ソート

コード

#include <cstdio>
#include <cctype>
#include <algorithm>
using namespace std;
const int maxq = 3e6;
struct Ques{
    int x,y,opt,id;//opt表示点的类型,1为修改点,0为询问点
    bool operator < (const Ques &b)const{//排序
        return x == b.x ? (y == b.y ? opt : y < b.y) : x < b.x;
    }
}ques[maxq],tmp[maxq];
int ques_tot,ans_tot,ans[maxq];
void cdq(int a,int b){//二维偏序
    if(a == b)return;
    int mid = (a + b) >> 1;
    cdq(a,mid),cdq(mid + 1,b);
    int posa = a,posb = mid + 1,pos = a,tot = 0;
    while(posa <= mid && posb <= b){
        if(ques[posa].y <= ques[posb].y)tot += ques[posa].opt,tmp[pos++] = ques[posa++];
        else ans[ques[posb].id] += tot,tmp[pos++] = ques[posb++];
    }
    while(posa <= mid)tmp[pos++] = ques[posa++];
    while(posb <= b)ans[ques[posb].id] += tot,tmp[pos++] = ques[posb++];
    for(int i = a;i <= b;i++)ques[i] = tmp[i];
}
int n,m;
int main(){
    scanf("%d %d",&n,&m);
    for(int x,y,i = 1;i <= n;i++)
        scanf("%d %d",&x,&y),ques[++ques_tot] = Ques{x,y,1,0};
    for(int a,b,c,d,i = 1;i <= m;i++){//拆点
        scanf("%d %d %d %d",&a,&b,&c,&d);
        ques[++ques_tot] = Ques{c,d,0,++ans_tot};
        ques[++ques_tot] = Ques{c,b - 1,0,++ans_tot};
        ques[++ques_tot] = Ques{a - 1,d,0,++ans_tot};
        ques[++ques_tot] = Ques{a - 1,b - 1,0,++ans_tot};
    }
    sort(ques + 1,ques + 1 + ques_tot);
    cdq(1,ques_tot);
    for(int i = 1;i + 3 <= ans_tot;i += 4)
        printf("%d\n",ans[i] - ans[i + 1] - ans[i + 2] + ans[i + 3]);
    return 0;
}

おすすめ

転載: www.cnblogs.com/colazcy/p/11515107.html