【POI2008】STR

题目大意
给出一个平面内的n个点,有一系列询问形如: x0,y0,x1,y1 ,输出平面的点中更接近 (x0,y0) 的个数,更接近 (x1,y1) 的个数,与两点距离相等的点的个数。

主要思想
可以按照询问分6种情况讨论!
【POI2008】STR_第1张图片

【POI2008】STR_第2张图片

【POI2008】STR_第3张图片
【POI2008】STR_第4张图片
以上六种情况中, p1 表示第一个点, p2 表示第二个点,他们之间的关系有六种,前三种分别为,他们组成的长方形的长与纵轴平行,他们组成的长方形的长与横轴平行,他们组成了一个正方形,后三种类似。每个图被分为三个部分:
1. 实线与阴影部分
2. 实线与阴影部分外偏 p1 的部分
3. 实线与阴影部分外偏 p2 的部分
对于每一种情况,将分出的部分再分成几块来算,用某个数据结构(比如树状数组)来维护就好了。
下面附一下代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<numeric>
#include<queue>
#include<functional>
#include<set>
#include<map>

#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
#define MAXN 100010

typedef double db;

using namespace std;

int get(){
    char ch;
    while (ch=getchar(),(ch<'0'||ch>'9')&& ch!='-');
    char c=ch;
    int s=(c!='-')*c-48;
    while (ch=getchar(),ch>='0'&&ch<='9')s=s*10+ch-48;
    return c=='-'?-s:s;
}

int n,m,z,p;
struct point{
    int x,y;
    db v;
}a[MAXN],b[MAXN];
int hx[MAXN],kx,hy[MAXN],ky,tree[MAXN],c[MAXN];
struct question{
    db x1,x2,y1,y2;
    int ty,ans1,ans2,ans3;
    db v1,v2;
    bool bz;
}q[MAXN];

void gettype(int x1,int y1,int x2,int y2,int i){
    q[i].bz=0;
    if(y1<y2){
        x1^=x2^=x1^=x2;
        y1^=y2^=y1^=y2;
        q[i].bz=1;
    }
    q[i].x1=x1;q[i].y1=y1;q[i].x2=x2;q[i].y2=y2;
    if (x1<x2){
        if (y1-y2>x2-x1)q[i].ty=1;
        if (y1-y2<x2-x1)q[i].ty=2;
        if (y1-y2==x2-x1)q[i].ty=3;
    }
    else{
        if (y1-y2>x1-x2)q[i].ty=4;
        if (y1-y2<x1-x2)q[i].ty=5;
        if (y1-y2==x1-x2)q[i].ty=6;
    }
}

bool cmp1(point i,point j){
    if (i.y!=j.y)return i.y<j.y;
    return i.x<j.x;
}

bool cmp2(point i,point j){
    if (i.x!=j.x)return i.x<j.x;
    return i.y<j.y;
}

bool cmp3(int i,int j){
    if (q[i].v1!=q[j].v1)return q[i].v1<q[j].v1;
    return q[i].v2<q[j].v2;
}

bool cmp4(point i,point j){
    if (i.v!=j.v)return i.v<j.v;
    return i.x<j.x;
}

void add(int x){
    while (x<=z){
        tree[x]++;
        x+=x & -x;
    }
}

int getsum(int x){
    int ans(0);
    while (x){
        ans+=tree[x];
        x=x-(x&-x);
    }
    return ans;
}

int askx(db x){
    int l=1,r=kx,ans(0);
    while (l<=r){
        int mid=(l+r)/2;
        if (hx[mid]>x)r=mid-1;
        else{
            l=mid+1;
            ans=mid;
        }
    }
    return ans;
}

int asky(db x){
    int l=1,r=ky,ans(0);
    while (l<=r){
        int mid=(l+r)/2;
        if (hy[mid]>x)r=mid-1;
        else{
            l=mid+1;
            ans=mid;
        }
    }
    return ans;
}

void type1(){
    int h1=1,tot=0;
    fo(i,1,p)
    if (q[i].ty==1)c[++tot]=i;
    sort(a+1,a+1+z,cmp1);
    ky=0;
    fo(i,1,z)
    if (a[i].y>a[i-1].y)hy[++ky]=a[i].y;
    sort(a+1,a+1+z,cmp2);
    kx=0;
    fo(i,1,z)
    if (a[i].x>a[i-1].x)hx[++kx]=a[i].x;
    fo(i,1,tot){
        int x=c[i];
        q[x].v1=q[x].x1;
        q[x].v2=q[x].y1-db(q[x].x2-q[x].x1+q[x].y1-q[x].y2)/2;
    }
    sort(c+1,c+1+tot,cmp3);
    fo(i,1,z){
        while (h1<=tot&&q[c[h1]].v1<=a[i].x){
            int x=c[h1++];
            int t1=getsum(asky(q[x].v2)),t2=getsum(asky(q[x].v2-1)),t3=getsum(ky);
            q[x].ans2+=t2;
            q[x].ans1+=t3-t1;
            if (int(q[x].v2)==q[x].v2)q[x].ans3+=t1-t2;
            else q[x].ans2+=t1-t2;
        }
        add(asky(a[i].y));
    }
    while(h1<=tot){
        int x=c[h1++];
        int t1=getsum(asky(q[x].v2)),t2=getsum(asky(q[x].v2-1)),t3=getsum(ky);
        q[x].ans2+=t2;
        q[x].ans1+=t3-t1;
        if (int(q[x].v2)==q[x].v2)q[x].ans3+=t1-t2;
        else q[x].ans2+=t1-t2;
    }

    fo(i,1,tot){
        int x=c[i];
        q[x].v1=q[x].x2;
        q[x].v2=q[x].y2+db(q[x].x2-q[x].x1+q[x].y1-q[x].y2)/2;
    }
    sort(c+1,c+1+tot,cmp3);
    fo(i,1,z)tree[i]=0;
    h1=tot;
    fd(i,z,1){
        while (h1&&q[c[h1]].v1>=a[i].x){
            int x=c[h1--];
            int t1=getsum(asky(q[x].v2)),t2=getsum(asky(q[x].v2-1)),t3=getsum(ky);
            q[x].ans2+=t2;
            q[x].ans1+=t3-t1;
            if (int(q[x].v2)==q[x].v2)q[x].ans3+=t1-t2;
            else q[x].ans2+=t1-t2;
        }
        add(asky(a[i].y));
    }
    while(h1){
        int x=c[h1--];
        int t1=getsum(asky(q[x].v2)),t2=getsum(asky(q[x].v2-1)),t3=getsum(ky);
        q[x].ans2+=t2;
        q[x].ans1+=t3-t1;
        if (int(q[x].v2)==q[x].v2)q[x].ans3+=t1-t2;
        else q[x].ans2+=t1-t2;
    }

    fo(i,1,z)a[i].v=a[i].y-a[i].x;
    sort(a+1,a+1+z,cmp4);
    fo(i,1,tot){
        int x=c[i];
        q[x].v1=q[x].v2-q[x].v1;
        q[x].v2=0;
    }
    sort(c+1,c+1+tot,cmp3);
    h1=1;
    fo(i,1,z)tree[i]=0;
    fo(i,1,z){
        while (h1<=tot&&q[c[h1]].v1<=a[i].v){
            int x=c[h1++];
            if (q[x].x2!=q[x].x1)
            q[x].ans2+=getsum(askx(q[x].x2))-getsum(askx(q[x].x1-1));
        }
        add(askx(a[i].x));
    }
    while (h1<=tot){
        int x=c[h1++];
        if (q[x].x2!=q[x].x1)
        q[x].ans2+=getsum(askx(q[x].x2))-getsum(askx(q[x].x1-1));
    }

    fo(i,1,z)tree[i]=0;
    h1=tot;
    fd(i,z,1){
        while (h1&&q[c[h1]].v1>=a[i].v){
            int x=c[h1--];
            q[x].ans1+=getsum(askx(q[x].x2))-getsum(askx(q[x].x1-1));
        }
        add(askx(a[i].x));
    }
    while (h1){
        int x=c[h1--];
        if (q[x].x2!=q[x].x1)
        q[x].ans1+=getsum(askx(q[x].x2))-getsum(askx(q[x].x1-1));
    }

    h1=1;
    int l;
    a[0].v=a[1].v-1;
    a[z+1].v=a[z].v+1;
    fo(i,1,z+1){
        if (a[i].v>a[i-1].v){
            while(h1<=tot&&q[c[h1]].v1<a[i-1].v)h1++;
            while(h1<=tot&&q[c[h1]].v1==a[i-1].v){
                int ll=l,rr=i-1,a1(-1),a2(-1),x=c[h1++];
                while (ll<=rr){
                    int mid=(ll+rr)/2;
                    if (a[mid].x<q[x].x1)ll=mid+1;
                    else{
                        rr=mid-1;
                        a1=mid;
                    }
                }
                ll=l;
                rr=i-1;
                while(ll<=rr){
                    int mid=(ll+rr)/2;
                    if (a[mid].x>q[x].x2)rr=mid-1;
                    else{
                        ll=mid+1;
                        a2=mid;
                    }
                }
                if (a1==-1||a2==-1)continue;
                q[x].ans3+=a2-a1+1;
            }
            l=i;
        }
    }
}

void type2(){
    int h1,tot(0);
    fo(i,1,p)
    if (q[i].ty==2)c[++tot]=i;

    sort(a+1,a+1+z,cmp1);
    fo(i,1,tot){
        int x=c[i];
        q[x].v2=q[x].x2-db(q[x].x2-q[x].x1+q[x].y1-q[x].y2)/2;
        q[x].v1=q[x].y2;
    }
    sort(c+1,c+1+tot,cmp3);
    h1=1;
    fo(i,1,z)tree[i]=0;
    fo(i,1,z){
        while(h1<=tot&&q[c[h1]].v1<=a[i].y){
            int x=c[h1++];
            int t1=getsum(askx(q[x].v2)),t2=getsum(askx(q[x].v2-1)),t3=i-1;
            int l1=q[x].ans1,l2=q[x].ans2,l3=q[x].ans3;
            q[x].ans1+=t2;
            q[x].ans2+=t3-t1;
            if (int(q[x].v2)==q[x].v2)q[x].ans3+=t1-t2;
            else q[x].ans1+=t1-t2;
        }
        add(askx(a[i].x));
    }
    while(h1<=tot){
        int x=c[h1++];
        int t1=getsum(askx(q[x].v2)),t2=getsum(askx(q[x].v2-1)),t3=z;
            int l1=q[x].ans1,l2=q[x].ans2,l3=q[x].ans3;
        q[x].ans1+=t2;
        q[x].ans2+=t3-t1;
        if (int(q[x].v2)==q[x].v2)q[x].ans3+=t1-t2;
        else q[x].ans1+=t1-t2;
    }

    fo(i,1,z)tree[i]=0;
    fo(i,1,tot){
        int x=c[i];
        q[x].v2=q[x].x1+db(q[x].x2-q[x].x1+q[x].y1-q[x].y2)/2;
        q[x].v1=q[x].y1;
    }
    sort(c+1,c+1+tot,cmp3);
    h1=tot;
    fd(i,z,1){
        while(h1&&q[c[h1]].v1>=a[i].y){
            int x=c[h1--];
            int t1=getsum(askx(q[x].v2)),t2=getsum(askx(q[x].v2-1)),t3=z-i;
            int l1=q[x].ans1,l2=q[x].ans2,l3=q[x].ans3;
            q[x].ans2+=t3-t1;
            q[x].ans1+=t2;
            if (int(q[x].v2)==q[x].v2)q[x].ans3+=t1-t2;
            else q[x].ans1+=t1-t2;
        }
        add(askx(a[i].x));
    } 
    while(h1){
        int x=c[h1--];
        int t1=getsum(askx(q[x].v2)),t2=getsum(askx(q[x].v2-1)),t3=z;
            int l1=q[x].ans1,l2=q[x].ans2,l3=q[x].ans3;
        q[x].ans2+=t3-t1;
        q[x].ans1+=t2;
        if (int(q[x].v2)==q[x].v2)q[x].ans3+=t1-t2;
        else q[x].ans1+=t1-t2;
    }

    fo(i,1,z)a[i].v=a[i].y-a[i].x;
    sort(a+1,a+1+z,cmp4);
    fo(i,1,tot){
        int x=c[i];
        q[x].v1=q[x].v1-q[x].v2;
        q[x].v2=0;
    }
    sort(c+1,c+1+tot,cmp3);
    h1=1;
    fo(i,1,z)tree[i]=0;
    fo(i,1,z){
        while (h1<=tot&&q[c[h1]].v1<=a[i].v){
            int x=c[h1++];
            q[x].ans2+=getsum(asky(q[x].y1))-getsum(asky(q[x].y2-1));
        }
        add(asky(a[i].y));
    }
    while (h1<=tot){
        int x=c[h1++];
        q[x].ans2+=getsum(asky(q[x].y1))-getsum(asky(q[x].y2-1));
    }

    fo(i,1,z)tree[i]=0;
    h1=tot;
    fd(i,z,1){
        while (h1&&q[c[h1]].v1>=a[i].v){
            int x=c[h1--];
            q[x].ans1+=getsum(asky(q[x].y1))-getsum(asky(q[x].y2-1));
        }
        add(asky(a[i].y));
    }
    while (h1){
        int x=c[h1--];
        q[x].ans1+=getsum(asky(q[x].y1))-getsum(asky(q[x].y2-1));
    }

    h1=1;
    int l=1;
    a[0].v=a[1].v-1;
    a[z+1].v=a[z].v+1;
    fo(i,1,z+1){
        if (a[i].v>a[i-1].v){
            while(h1<=tot&&q[c[h1]].v1<a[i-1].v)h1++;
            while(h1<=tot&&q[c[h1]].v1==a[i-1].v){
                int ll=l,rr=i-1,a1(-1),a2(-1),x=c[h1++];
                db len=(q[x].x2-q[x].x1+q[x].y1-q[x].y2)/2;
                while (ll<=rr){
                    int mid=(ll+rr)/2;
                    if (a[mid].x<q[x].x2-len)ll=mid+1;
                    else{
                        rr=mid-1;
                        a1=mid;
                    }
                }
                ll=l;
                rr=i-1;
                while(ll<=rr){
                    int mid=(ll+rr)/2;
                    if (a[mid].x>q[x].x1+len)rr=mid-1;
                    else{
                        ll=mid+1;
                        a2=mid;
                    }
                }
                if (a1==-1||a2==-1)continue;
                q[x].ans3+=a2-a1+1;
            }
            l=i;
        }
    }
}

void type3(){
    int h1,tot(0);
    fo(i,1,p)
    if (q[i].ty==3)c[++tot]=i;

    fo(i,1,z)tree[i]=0;
    sort(a+1,a+1+z,cmp2);
    fo(i,1,tot){
        int x=c[i];
        q[x].v1=q[x].x1;
        q[x].v2=q[x].y2;
    }
    sort(c+1,c+1+tot,cmp3);
    h1=1;
    fo(i,1,z){
        while(h1<=tot&&q[c[h1]].v1<=a[i].x){
            int x=c[h1++];
            int t1=getsum(asky(q[x].v2)),t2=getsum(ky);
            q[x].ans3+=t1;
            q[x].ans1+=t2-t1;
        }
        add(asky(a[i].y));
    }
    while(h1<=tot){
        int x=c[h1++];
        int t1=getsum(asky(q[x].v2)),t2=getsum(ky);
        q[x].ans3+=t1;
        q[x].ans1+=t2-t1;
    }

    fo(i,1,z)tree[i]=0;
    fo(i,1,tot){
        int x=c[i];
        q[x].v1=q[x].x2;
        q[x].v2=q[x].y1;
    }
    sort(c+1,c+1+tot,cmp3);
    h1=tot;
    fd(i,z,1){
        while(h1&&q[c[h1]].v1>=a[i].x){
            int x=c[h1--];
            int t1=getsum(ky),t2=getsum(asky(q[x].v2-1));
            q[x].ans2+=t2;
            q[x].ans3+=t1-t2;
        }
        add(asky(a[i].y));
    }
    while(h1){
        int x=c[h1--];
        int t1=getsum(ky),t2=getsum(asky(q[x].v2-1));
        q[x].ans2+=t2;
        q[x].ans3+=t1-t2;
    }

    fo(i,1,z)a[i].v=a[i].y-a[i].x;
    sort(a+1,a+1+z,cmp4);
    fo(i,1,tot){
        int x=c[i];
        q[x].v1=q[x].v2-q[x].v1;
        q[x].v2=0;
    }
    sort(c+1,c+1+tot,cmp3);
    h1=1;
    fo(i,1,z)tree[i]=0;
    fo(i,1,z){
        while (h1<=tot&&q[c[h1]].v1<=a[i].v){
            int x=c[h1++];
            q[x].ans2+=getsum(askx(q[x].x2))-getsum(askx(q[x].x1));
            q[x].ans3+=getsum(askx(q[x].x1))-getsum(askx(q[x].x1-1));
        }
        add(askx(a[i].x));
    }
    while (h1<=tot){
        int x=c[h1++];
        q[x].ans2+=getsum(askx(q[x].x2))-getsum(askx(q[x].x1));
            q[x].ans3+=getsum(askx(q[x].x1))-getsum(askx(q[x].x1-1));
    }
    fo(i,1,z)tree[i]=0;
    h1=tot;
    fd(i,z,1){
        while (h1&&q[c[h1]].v1>=a[i].v){
            int x=c[h1--];
            q[x].ans1+=getsum(askx(q[x].x2-1))-getsum(askx(q[x].x1-1));
            q[x].ans3+=getsum(askx(q[x].x2))-getsum(askx(q[x].x2-1));
        }
        add(askx(a[i].x));
    }
    while (h1){
        int x=c[h1--];
        q[x].ans1+=getsum(askx(q[x].x2-1))-getsum(askx(q[x].x1-1));
        q[x].ans3+=getsum(askx(q[x].x2))-getsum(askx(q[x].x2-1));
    }

    h1=1;
    int l;
    a[0].v=a[1].v-1;
    a[z+1].v=a[z].v+1;
    fo(i,1,z+1){
        if (a[i].v>a[i-1].v){
            while(h1<=tot&&q[c[h1]].v1<a[i-1].v)h1++;
            while(h1<=tot&&q[c[h1]].v1==a[i-1].v){
                int ll=l,rr=i-1,a1(-1),a2(-1),x=c[h1++];
                while (ll<=rr){
                    int mid=(ll+rr)/2;
                    if (a[mid].x<q[x].x1)ll=mid+1;
                    else{
                        rr=mid-1;
                        a1=mid;
                    }
                }
                ll=l;
                rr=i-1;
                while(ll<=rr){
                    int mid=(ll+rr)/2;
                    if (a[mid].x>q[x].x2)rr=mid-1;
                    else{
                        ll=mid+1;
                        a2=mid;
                    }
                }
                if (a1==-1||a2==-1)continue;
                q[x].ans3+=a2-a1+1;
            }
            l=i;
        }
    }
}

void type4(){
    int h1,tot(0);
    fo(i,1,p)
    if (q[i].ty==4)c[++tot]=i;

    sort(a+1,a+1+z,cmp2);
    fo(i,1,tot){
        int x=c[i];
        q[x].v1=q[x].x2;
        q[x].v2=q[x].y2+db(q[x].x1-q[x].x2+q[x].y1-q[x].y2)/2;
    }
    fo(i,1,z)tree[i]=0;
    sort(c+1,c+1+tot,cmp3);
    h1=1;
    fo(i,1,z){
        while(h1<=tot&&q[c[h1]].v1<=a[i].x){
            int x=c[h1++];
            int t1=getsum(asky(q[x].v2)),t2=getsum(asky(q[x].v2-1)),t3=getsum(ky);
            q[x].ans1+=t3-t1;
            q[x].ans2+=t2;
            if (int(q[x].v2)==q[x].v2)q[x].ans3+=t1-t2;
            else q[x].ans2+=t1-t2;
        }
        add(asky(a[i].y));
    }
    while(h1<=tot){
        int x=c[h1++];
        int t1=getsum(asky(q[x].v2)),t2=getsum(asky(q[x].v2-1)),t3=getsum(ky);
        q[x].ans1+=t3-t1;
        q[x].ans2+=t2;
        if (int(q[x].v2)==q[x].v2)q[x].ans3+=t1-t2;
        else q[x].ans2+=t1-t2;
    }
    fo(i,1,z)tree[i]=0;
    fo(i,1,tot){
        int x=c[i];
        q[x].v1=q[x].x1;
        q[x].v2=q[x].y1-db(q[x].x1-q[x].x2+q[x].y1-q[x].y2)/2;
    }
    sort(c+1,c+1+tot,cmp3);
    h1=tot;
    fd(i,z,1){
        while (h1&&q[c[h1]].v1>=a[i].x){
            int x=c[h1--];
            int t1=getsum(asky(q[x].v2)),t2=getsum(asky(q[x].v2-1)),t3=getsum(ky);
            q[x].ans1+=t3-t1;
            q[x].ans2+=t2;
            if (int(q[x].v2)==q[x].v2)q[x].ans3+=t1-t2;
            else q[x].ans2+=t1-t2;
        }
        add(asky(a[i].y));
    }
    while (h1){
        int x=c[h1--];
        int t1=getsum(asky(q[x].v2)),t2=getsum(asky(q[x].v2-1)),t3=getsum(ky);
        q[x].ans1+=t3-t1;
        q[x].ans2+=t2;
        if (int(q[x].v2)==q[x].v2)q[x].ans3+=t1-t2;
        else q[x].ans2+=t1-t2;
    }

    fo(i,1,z)tree[i]=0;
    fo(i,1,tot){
        int x=c[i];
        q[x].v1=q[x].v1+q[x].v2;
        q[x].v2=0;
    }
    sort(c+1,c+1+tot,cmp3);
    fo(i,1,z)a[i].v=a[i].x+a[i].y;
    sort(a+1,a+1+z,cmp4);
    h1=1;
    fo(i,1,z){
        while (h1<=tot&&q[c[h1]].v1<=a[i].v){
            int x=c[h1++];
            q[x].ans2+=getsum(askx(q[x].x1))-getsum(askx(q[x].x2-1));
        }
        add(askx(a[i].x));
    }
    while (h1<=tot){
        int x=c[h1++];
        q[x].ans2+=getsum(askx(q[x].x1))-getsum(askx(q[x].x2-1));
    }

    fo(i,1,z)tree[i]=0;
    h1=tot;
    fd(i,z,1){
        while (h1&&q[c[h1]].v1>=a[i].v){
            int x=c[h1--];
            q[x].ans1+=getsum(askx(q[x].x1))-getsum(askx(q[x].x2-1));
        }
        add(askx(a[i].x));
    }
    while (h1){
        int x=c[h1--];
        q[x].ans1+=getsum(askx(q[x].x1))-getsum(askx(q[x].x2-1));
    }

    h1=1;
    int l;
    a[0].v=a[1].v-1;
    a[z+1].v=a[z].v+1;
    fo(i,1,z+1){
        if (a[i].v>a[i-1].v){
            while(h1<=tot&&q[c[h1]].v1<a[i-1].v)h1++;
            while(h1<=tot&&q[c[h1]].v1==a[i-1].v){
                int ll=l,rr=i-1,a1(-1),a2(-1),x=c[h1++];
                while (ll<=rr){
                    int mid=(ll+rr)/2;
                    if (a[mid].x<q[x].x2)ll=mid+1;
                    else{
                        rr=mid-1;
                        a1=mid;
                    }
                }
                ll=l;
                rr=i-1;
                while(ll<=rr){
                    int mid=(ll+rr)/2;
                    if (a[mid].x>q[x].x1)rr=mid-1;
                    else{
                        ll=mid+1;
                        a2=mid;
                    }
                }
                if (a1==-1||a2==-1)continue;
                q[x].ans3+=a2-a1+1;
            }
            l=i;
        }
    }
}

void type5(){
    int h1,tot(0);
    fo(i,1,p)
    if (q[i].ty==5)c[++tot]=i;

    sort(a+1,a+1+z,cmp1);
    fo(i,1,tot){
        int x=c[i];
        q[x].v2=q[x].x2+db(q[x].x1-q[x].x2+q[x].y1-q[x].y2)/2;
        q[x].v1=q[x].y2;
    }
    sort(c+1,c+1+tot,cmp3);
    h1=1;
    fo(i,1,z)tree[i]=0;
    fo(i,1,z){
        while(h1<=tot&&q[c[h1]].v1<=a[i].y){
            int x=c[h1++];
            int t1=getsum(askx(q[x].v2)),t2=getsum(askx(q[x].v2-1)),t3=i-1;
            q[x].ans2+=t2;
            q[x].ans1+=t3-t1;
            if (int(q[x].v2)==q[x].v2)q[x].ans3+=t1-t2;
            else q[x].ans2+=t1-t2;
        }
        add(askx(a[i].x));
    }
    while(h1<=tot){
        int x=c[h1++];
        int t1=getsum(askx(q[x].v2)),t2=getsum(askx(q[x].v2-1));
        q[x].ans2+=t2;
        q[x].ans1+=z-t1;
        if (int(q[x].v2)==q[x].v2)q[x].ans3+=t1-t2;
        else q[x].ans2+=t1-t2;
    }

    fo(i,1,z)tree[i]=0;
    fo(i,1,tot){
        int x=c[i];
        q[x].v2=q[x].x1-db(q[x].x1-q[x].x2+q[x].y1-q[x].y2)/2;
        q[x].v1=q[x].y1;
    }
    sort(c+1,c+1+tot,cmp3);
    h1=tot;
    fd(i,z,1){
        while(h1&&q[c[h1]].v1>=a[i].y){
            int x=c[h1--];
            int t1=getsum(askx(q[x].v2)),t2=getsum(askx(q[x].v2-1)),t3=z-i;
            q[x].ans2+=t2;
            q[x].ans1+=t3-t1;
            if (int(q[x].v2)==q[x].v2)q[x].ans3+=t1-t2;
            else q[x].ans2+=t1-t2;
        }
        add(askx(a[i].x));
    } 
    while(h1){
        int x=c[h1--];
        int t1=getsum(askx(q[x].v2)),t2=getsum(askx(q[x].v2-1)),t3=z;
        q[x].ans2+=t2;
        q[x].ans1+=z-t1;
        if (int(q[x].v2)==q[x].v2)q[x].ans3+=t1-t2;
        else q[x].ans2+=t1-t2;
    }

    fo(i,1,z)tree[i]=0;
    fo(i,1,tot){
        int x=c[i];
        q[x].v1=q[x].v1+q[x].v2;
        q[x].v2=0;
    }
    sort(c+1,c+1+tot,cmp3);
    fo(i,1,z)a[i].v=a[i].x+a[i].y;
    sort(a+1,a+1+z,cmp4);
    h1=1;
    fo(i,1,z){
        while (h1<=tot&&q[c[h1]].v1<=a[i].v){
            int x=c[h1++];
            q[x].ans2+=getsum(asky(q[x].y1))-getsum(asky(q[x].y2-1));
        }
        add(asky(a[i].y));
    }
    while (h1<=tot){
        int x=c[h1++];
        q[x].ans2+=getsum(asky(q[x].y1))-getsum(asky(q[x].y2-1));
    }

    fo(i,1,z)tree[i]=0;
    h1=tot;
    fd(i,z,1){
        while (h1&&q[c[h1]].v1>=a[i].v){
            int x=c[h1--];
            q[x].ans1+=getsum(asky(q[x].y1))-getsum(asky(q[x].y2-1));
        }
        add(asky(a[i].y));
    }
    while (h1){
        int x=c[h1--];
        q[x].ans1+=getsum(asky(q[x].y1))-getsum(asky(q[x].y2-1));
    }


    h1=1;
    int l=1;
    a[0].v=a[1].v-1;
    a[z+1].v=a[z].v+1;
    fo(i,1,z+1){
        if (a[i].v>a[i-1].v){
            while(h1<=tot&&q[c[h1]].v1<a[i-1].v)h1++;
            while(h1<=tot&&q[c[h1]].v1==a[i-1].v){
                int ll=l,rr=i-1,a1(-1),a2(-1),x=c[h1++];
                db len=(q[x].x1-q[x].x2+q[x].y1-q[x].y2)/2;
                while (ll<=rr){
                    int mid=(ll+rr)/2;
                    if (a[mid].x<q[x].x1-len)ll=mid+1;
                    else{
                        rr=mid-1;
                        a1=mid;
                    }
                }
                ll=l;
                rr=i-1;
                while(ll<=rr){
                    int mid=(ll+rr)/2;
                    if (a[mid].x>q[x].x2+len)rr=mid-1;
                    else{
                        ll=mid+1;
                        a2=mid;
                    }
                }
                if (a1==-1||a2==-1)continue;
                q[x].ans3+=a2-a1+1;
            }
            l=i;
        }
    }
}

void type6(){
    int h1,tot(0);
    fo(i,1,p)
    if (q[i].ty==6)c[++tot]=i;

    fo(i,1,z)tree[i]=0;
    sort(a+1,a+1+z,cmp2);
    fo(i,1,tot){
        int x=c[i];
        q[x].v1=q[x].x2;
        q[x].v2=q[x].y1;
    }
    sort(c+1,c+1+tot,cmp3);
    h1=1;
    fo(i,1,z){
        while(h1<=tot&&q[c[h1]].v1<=a[i].x){
            int x=c[h1++];
            int t1=getsum(asky(q[x].v2-1)),t3=i-1;
            q[x].ans2+=t1;
            q[x].ans3+=t3-t1;
        }
        add(asky(a[i].y));
    }
    while(h1<=tot){
        int x=c[h1++];
        int t1=getsum(asky(q[x].v2-1)),t3=z;
        q[x].ans2+=t1;
        q[x].ans3+=t3-t1;
    }

    fo(i,1,z)tree[i]=0;
    fo(i,1,tot){
        int x=c[i];
        q[x].v1=q[x].x1;
        q[x].v2=q[x].y2;
    }
    sort(c+1,c+1+tot,cmp3);
    h1=tot;
    fd(i,z,1){
        while(h1&&q[c[h1]].v1>=a[i].x){
            int x=c[h1--];
            int t1=getsum(ky),t2=getsum(asky(q[x].v2));
            q[x].ans3+=t2;
            q[x].ans1+=t1-t2;
        }
        add(asky(a[i].y));
    }
    while(h1){
        int x=c[h1--];
        int t1=getsum(ky),t2=getsum(asky(q[x].v2));
        q[x].ans3+=t2;
        q[x].ans1+=t1-t2;
    }

    fo(i,1,z)tree[i]=0;
    fo(i,1,tot){
        int x=c[i];
        q[x].v1=q[x].v1+q[x].v2;
        q[x].v2=0;
    }
    sort(c+1,c+1+tot,cmp3);
    fo(i,1,z)a[i].v=a[i].x+a[i].y;
    sort(a+1,a+1+z,cmp4);
    h1=1;
    fo(i,1,z){
        while (h1<=tot&&q[c[h1]].v1<=a[i].v){
            int x=c[h1++];
            q[x].ans2+=getsum(askx(q[x].x1-1))-getsum(askx(q[x].x2-1));
            q[x].ans3+=getsum(askx(q[x].x1))-getsum(askx(q[x].x1-1));
        }
        add(askx(a[i].x));
    }
    while (h1<=tot){
        int x=c[h1++];
        q[x].ans2+=getsum(askx(q[x].x1-1))-getsum(askx(q[x].x2-1));
        q[x].ans3+=getsum(askx(q[x].x1))-getsum(askx(q[x].x1-1));
    }

    fo(i,1,z)tree[i]=0;
    h1=tot;
    fd(i,z,1){
        while (h1&&q[c[h1]].v1>=a[i].v){
            int x=c[h1--];
            q[x].ans1+=getsum(askx(q[x].x1))-getsum(askx(q[x].x2));
            q[x].ans3+=getsum(askx(q[x].x2))-getsum(askx(q[x].x2-1));
        }
        add(askx(a[i].x));
    }
    while (h1){
        int x=c[h1--];
        q[x].ans1+=getsum(askx(q[x].x1))-getsum(askx(q[x].x2));
        q[x].ans3+=getsum(askx(q[x].x2))-getsum(askx(q[x].x2-1));
    }

    h1=1;
    int l;
    a[0].v=a[1].v-1;
    a[z+1].v=a[z].v+1;
    fo(i,1,z+1){
        if (a[i].v>a[i-1].v){
            while(h1<=tot&&q[c[h1]].v1<a[i-1].v)h1++;
            while(h1<=tot&&q[c[h1]].v1==a[i-1].v){
                int ll=l,rr=i-1,a1(-1),a2(-1),x=c[h1++];
                while (ll<=rr){
                    int mid=(ll+rr)/2;
                    if (a[mid].x<q[x].x2)ll=mid+1;
                    else{
                        rr=mid-1;
                        a1=mid;
                    }
                }
                ll=l;
                rr=i-1;
                while(ll<=rr){
                    int mid=(ll+rr)/2;
                    if (a[mid].x>q[x].x1)rr=mid-1;
                    else{
                        ll=mid+1;
                        a2=mid;
                    }
                }
                if (a1==-1||a2==-1)continue;
                q[x].ans3+=a2-a1+1;
            }
            l=i;
        }
    }
}

void getans(){
    fo(i,1,p)
    if (q[i].bz)printf("%d %d %d\n",q[i].ans2,q[i].ans1,q[i].ans3);
    else printf("%d %d %d\n",q[i].ans1,q[i].ans2,q[i].ans3);
}

int main(){
    n=get();m=get();z=get();p=get();
    fo(i,1,z)a[i].x=b[i].x=get(),a[i].y=b[i].y=get();
    fo(i,1,p){
        int x1=get(),y1=get(),x2=get(),y2=get();
        gettype(x1,y1,x2,y2,i);
    }
    type1();
    type2();
    type3();
    type4();
    type5();
    type6();
    getans();
}

你可能感兴趣的:(poi,解题报告)