【JZOJ3893】【NOIP2014模拟10.25A组】画矩形

来源:互联网 发布:自制西门子编程线 编辑:程序博客网 时间:2024/05/22 06:20

Description

这里写图片描述

Data Constraint

这里写图片描述

Solution

后来听说这是一道CDQ分治的题目。
对于一个矩形,我们可以在它的左的左下角和右上角打一个+1标记,左上角和右下角打一个-1标记。那么对于一个点的询问就成了询问它左下角的和为多少。我们可以把所有插入拆成两个左边和右边的对一列的操作,和询问放在一起按横坐标进行排序。然后二分时间,对于每次二分的时间t,我们把区间内时间<=t的插入放入树状数组内统计,然后计算区间内时间>=t的方案,然后再把区间内时间

Code

#include<iostream>#include<cmath>#include<cstring>#include<cstdio>#include<algorithm>#define ll long longusing namespace std;const int maxn=4e5+5;struct code{    int a,l,r,t,bz;}a[maxn],b[maxn];int f[maxn],ans1[maxn];int n,i,t,j,k,l,num,x,y,z,ans,num1;bool cmp(code x,code y){    return x.a<y.a || x.a==y.a && x.bz<y.bz;}int lowbit(int x){    return x&(-x);}void insert(int x,int z){    if (x>maxn-5) return;     f[x]+=z;insert(x+lowbit(x),z);}int find(int x){    if (x<1) return 0;    return f[x]+find(x-lowbit(x));}void dg(int l,int r){    int mid,i,j,t;    if (l==r) return;    mid=(l+r)/2;     for (i=l;i<=r;i++){        if (a[i].t<=mid && a[i].bz!=1){            if (a[i].bz==0) insert(a[i].l,1),insert(a[i].r+1,-1);            else insert(a[i].l,-1),insert(a[i].r+1,1);        }else if (a[i].bz==1 && a[i].t>=mid) ans1[a[i].r]+=find(a[i].l);    }    for (i=l;i<=r;i++)        if (a[i].t<=mid && a[i].bz!=1){            if (a[i].bz==0) insert(a[i].l,-1),insert(a[i].r+1,+1);            else insert(a[i].l,+1),insert(a[i].r+1,-1);        }    num=l-1;    if (r-l==1) return;    for (i=l;i<=r;i++)        if (a[i].t<mid) b[++num]=a[i];    num++;     for (i=l;i<=r;i++)        if (a[i].t>mid) b[++num]=a[i];    for (i=l;i<=r;i++)        a[i]=b[i];    dg(l,mid-1);    dg(mid+1,r);}int main(){//  freopen("data.in","r",stdin);freopen("data.out","w",stdout);    scanf("%d",&n);    for (i=1;i<=n;i++){        scanf("%d%d%d",&z,&x,&y);x++;y++;        if (z) a[++num].a=x,a[num].l=y,a[num].t=num,a[num].bz=1,a[num].r=++num1;        else{            a[++num].t=num,a[++num].t=num;a[num-1].a=x;scanf("%d%d",&a[num].a,&a[num].r);            a[num].a++;a[num].r++;a[num-1].l=a[num].l=y;a[num-1].r=a[num].r;            a[num-1].bz=0,a[num].bz=2;        }    }    sort(a+1,a+num+1,cmp);    dg(1,num);    for (i=1;i<=num1;i++)        printf("%d\n",ans1[i]);}
1 0
原创粉丝点击