CDQ partition template title

P3810 dimensional partial sequence (Mo flowers)

CDQ partition template title
first dimension direct sequencing, the second dimension using divide and conquer, the third dimension with Fenwick tree

#include<bits/stdc++.h>
using namespace std;
const int maxx = 1e5+10;
struct node
{
    int a,b,c,w,s;
}e[maxx],g[maxx];
bool cmp(node x,node y)
{
    if(x.a!=y.a)return x.a<y.a;
    if(x.b!=y.b)return x.b<y.b;
    return x.c<y.c;
}
int t[2*maxx],ans[maxx];
int n,m;
void add(int x,int c)
{
    for(int i=x;i<=m;i+=(i&(-i)))t[i]+=c;
}
int getsum(int x)
{
    int res=0;
    for(int i=x;i>0;i-=(i&(-i)))res+=t[i];
    return res;
}
void cdq(int l,int r)
{
    if(l==r)return;
    int mid=(l+r)/2;
    cdq(l,mid);cdq(mid+1,r);
    int p=l,q=mid+1,cnt=l;
    while(p<=mid&&q<=r)
    {
        if(e[p].b<=e[q].b)add(e[p].c,e[p].w),g[cnt++]=e[p++];
        else e[q].s+=getsum(e[q].c),g[cnt++]=e[q++];
    }
    while(p<=mid)add(e[p].c,e[p].w),g[cnt++]=e[p++];
    while(q<=r)e[q].s+=getsum(e[q].c),g[cnt++]=e[q++];
    for(int i=l;i<=mid;i++)add(e[i].c,-e[i].w);
    for(int i=l;i<=r;i++)e[i]=g[i];
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
    {
        scanf("%d%d%d",&e[i].a,&e[i].b,&e[i].c);
        e[i].w=1;
    }
    sort(e+1,e+1+n,cmp);
    int tot=1;
    for(int i=2;i<=n;i++)
    {
        if(e[i].a==e[tot].a&&e[i].b==e[tot].b&&e[i].c==e[tot].c)e[tot].w++;
        else e[++tot]=e[i];
    }
    cdq(1,tot);
    for(int i=1;i<=tot;i++)ans[e[i].s+e[i].w-1]+=e[i].w;
    for(int i=0;i<n;i++)printf("%d\n",ans[i]);
    return 0;
}

2018SEERC Points and Rectangles(洛谷P5873)

The meaning of problems:
a two-dimensional plane, two operations:
. 1 XY: In (x, y) to put a point
2 x1, y1, x2, y2 : put a lower left (x1, y1), the upper right corner (x2, y2) matrix.
After each operation requires the sum of the number of all the matrix points contained.

The first dimension is operating sequence, the second dimension is x, y for the third dimension
, respectively, and each dot matrices statistical contribution.

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxx = 4e5+10;
struct node
{
    int op,x,y,id;
    bool operator < (const node &t)const
    {
        return id<t.id;
    }
}e[maxx],g[maxx];
int a[maxx],t[maxx],ans[maxx];
int tot=0,num=0;
vector<int>v1,v2;
void add(int x,int c)
{
    for(int i=x;i<=num;i+=(i&(-i)))t[i]+=c;
}
int getsum(int x)
{
    int res=0;
    for(int i=x;i>0;i-=(i&(-i)))res+=t[i];
    return res;
}
void cdq1(int l,int r) //点对矩阵贡献
{
    if(l==r)return;
    int mid=(l+r)/2;
    cdq1(l,mid),cdq1(mid+1,r);
    int p=l,q=mid+1,cnt=l;
    while(p<=mid&&q<=r)
    {
        if(e[p].x<=e[q].x)
        {
            if(e[p].op==1)add(e[p].y,1),v1.push_back(e[p].y);
            g[cnt++]=e[p++];
        }
        else
        {
            if(e[q].op==2)ans[e[q].id]+=getsum(e[q].y);
            else if(e[q].op==3)ans[e[q].id]-=getsum(e[q].y);
            g[cnt++]=e[q++];
        }
    }
    while(p<=mid)g[cnt++]=e[p++];
    while(q<=r)
    {
        if(e[q].op==2)ans[e[q].id]+=getsum(e[q].y);
        else if(e[q].op==3)ans[e[q].id]-=getsum(e[q].y);
        g[cnt++]=e[q++];
    }
    for(int i=l;i<=r;i++)e[i]=g[i];
    for(int i=0;i<v1.size();i++)add(v1[i],-1);
    v1.clear();
}
//(x1-1,y1-1),(x1-1,y2),(x2,y1-1),(x2,y2)对应贡献为1,-1,-1,1
void cdq2(int l,int r) //矩阵对点贡献
{
    if(l==r)return;
    int mid=(l+r)/2;
    cdq2(l,mid),cdq2(mid+1,r);
    int p=l,q=mid+1,cnt=l;
    while(p<=mid&&q<=r)
    {
        if(e[p].x<e[q].x)
        {
            if(e[p].op==2)add(e[p].y,1),v1.push_back(e[p].y);
            else if(e[p].op==3)add(e[p].y,-1),v2.push_back(e[p].y);
            g[cnt++]=e[p++];
        }
        else
        {
            if(e[q].op==1)ans[e[q].id]+=getsum(e[q].y-1);  //注意这里要减1
            g[cnt++]=e[q++];
        }
    }
    while(p<=mid)g[cnt++]=e[p++];
    while(q<=r)
    {
        if(e[q].op==1)ans[e[q].id]+=getsum(e[q].y-1);
        g[cnt++]=e[q++];
    }
    for(int i=l;i<=r;i++)e[i]=g[i];
    for(int i=0;i<v1.size();i++)add(v1[i],-1);
    for(int i=0;i<v2.size();i++)add(v2[i],1);
    v1.clear(),v2.clear();
}
int main()
{
    int n;
    scanf("%d",&n);
    int op,x1,y1,x2,y2;
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&op);
        if(op==1)
        {
            scanf("%d%d",&x1,&y1);
            e[++tot]=node{op,x1,y1,i};
            a[++num]=x1,a[++num]=y1;
        }
        else
        {
            scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
            e[++tot]=node{op,x1-1,y1-1,i};
            e[++tot]=node{op,x2,y2,i};
            e[++tot]=node{op+1,x1-1,y2,i};
            e[++tot]=node{op+1,x2,y1-1,i};
            a[++num]=x1-1,a[++num]=y1-1,a[++num]=x2,a[++num]=y2;
        }
    }
    sort(a+1,a+1+num);
    num=unique(a+1,a+1+num)-a-1;
    for(int i=1;i<=tot;i++)
    {
        e[i].x=lower_bound(a+1,a+1+num,e[i].x)-a;
        e[i].y=lower_bound(a+1,a+1+num,e[i].y)-a;
    }
    cdq1(1,tot);
    sort(e+1,e+1+tot);
    cdq2(1,tot);
    LL res=0;
    for(int i=1;i<=n;i++)
    {
        res+=ans[i];
        printf("%lld\n",res);
    }
    return 0;
}

Guess you like

Origin www.cnblogs.com/HooYing/p/12459709.html