园丁的烦恼 树状数组 + 离散化 +排序

非常simple的二维数点问题。
1. 读入(这TM不是屁话)
2. 离散坐标(也是P话)
3. 按照从左到右,从下到上排序
4. 离线处理每一个矩阵,可以提前存好是加还是减,总之空间开4倍
5. 不要忘记开O2哟~

#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
const int maxm=5000000+5;
const int maxn=5000000+2;
int x[maxm], y[maxm], idx[maxm],A[maxm]; 
int C[maxm], ans[maxm];
int X[maxm];
int cmp(int i,int j)
{
    if(y[i]==y[j]){
        if(x[i]==x[j])return abs(idx[i])<abs(idx[j]);
        return x[i]<x[j];
    }
    return y[i]<y[j];
}
int lowbit(int t){return t&(-t);}
void update(int x,int delta)
{
    while(x<maxn)C[x]+=delta,x+=lowbit(x);
}
int query(int x)
{
    int tmp=0;
    while(x>0)tmp+=C[x], x-=lowbit(x);
    return tmp;
}
int main()
{
    int n,m,cnt; 
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;++i){
        scanf("%d%d",&x[i],&y[i]);
             idx[i]=0;
        ++x[i];
        X[i]=x[i];
        ++y[i];
    }
    cnt=n;
    for(int i=1;i<=m;++i)
    {
        int a,b,c,d;
        scanf("%d%d%d%d",&a,&b,&c,&d);
        ++a;++b;++c;++d;                         //真实坐标
        ++cnt;
        x[cnt]=a-1, y[cnt]=b-1, idx[cnt]=1, X[cnt]=a-1;
        ++cnt;
        x[cnt]=c, y[cnt]=b-1, idx[cnt]=-1, X[cnt]=c;
        ++cnt;
        x[cnt]=a-1, y[cnt]=d, idx[cnt]=-1, X[cnt]=a-1;
        ++cnt;
        x[cnt]=c, y[cnt]=d, idx[cnt]=1, X[cnt]=c;
    }
    sort(X+1,X+1+cnt);
    for(int i=1;i<=cnt;++i){
        A[i]=i;
        x[i]=lower_bound(X+1,X+1+cnt,x[i])-X;
    }
    sort(A+1,A+1+cnt,cmp);
    for(int i=1;i<=cnt;++i)
    {
        int cur=A[i];
        if(idx[cur]==0)update(x[cur], 1);
        else
        {
            int h=query(x[cur]);
            ans[cur]=(idx[cur]*h);
        }
    }
    for(int i=n+1;i<=cnt;i+=4)
    {
        int h=ans[i]+ans[i+1]+ans[i+2]+ans[i+3];
        printf("%d
",h);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/guangheli/p/9845218.html