ShadyPi的博客

CSDN当存档,更好看的博客:http://touhou.studio/

Luogu3810 三维偏序(陌上花开)

原题链接:https://www.luogu.org/problemnew/show/P3810

【模板】三维偏序(陌上花开)

题目背景

这是一道模板题

可以使用bitset,CDQ分治,K-DTree等方式解决。

题目描述

n 个元素,第i 个元素有aibici三个属性,设f(i) 表示满足ajaibjbicjcij 的数量。

对于 d[0,n),求f(i)=d 的数量

输入输出格式
输入格式:

第一行两个整数nk ,分别表示元素数量和最大属性值。

之后n行,每行三个整数aibici,分别表示三个属性值。

输出格式:

输出 n行,第d+1行表示f(i)=di 的数量。

输入输出样例
输入样例#1:

10 3
3 3 3
2 3 3
2 3 1
3 1 1
3 1 2
1 3 1
1 1 2
1 2 2
1 3 2
1 2 1

输出样例#1:

3
1
3
0
1
0
1
0
0
1

说明

1n100000,1k200000

题解

考虑使用cdq分治,第一维直接排序搞掉,第二维cdq搞成离线,最后一位上数据结构即可。

左半边对右半边的贡献很好统计,左边为单点加,右边为区间求和。

代码
#include<bits/stdc++.h>
using namespace std;
const int M=1e6+5;
struct sd{int p,q,r,sum,cot,id;};
bool cmp1(sd a,sd b)
{
    if(a.p!=b.p)return a.p<b.p;
    if(a.q!=b.q)return a.q<b.q;
    return a.r<b.r;
}
bool cmp2(sd a,sd b){return a.q==b.q?(a.r==b.r?a.p<b.p:a.r<b.r):a.q<b.q;}
bool operator !=(sd a,sd b){return a.p!=b.p||a.q!=b.q||a.r!=b.r;}
int sum[M],ans[M],n,tot,base=1;
sd x[M],que[M];
void in()
{
    int a;
    scanf("%d%d",&n,&a);
    while(base<a)base<<=1;
    for(int i=1;i<=n;++i)scanf("%d%d%d",&x[i].p,&x[i].q,&x[i].r);
}
void add(int v,int s){v+=base;for(;v;v>>=1)sum[v]+=s;}
int query(int le,int ri)
{
    int ans=0;le+=base;ri+=base;
    for(;le^ri^1;le>>=1,ri>>=1)
    {
        if(le&1^1)ans+=sum[le+1];
        if(ri&1)ans+=sum[ri-1];
    }
    return ans;
}
void cdq(int le,int ri)
{
    if(le==ri)return;
    int mid=(le+ri)>>1;
    cdq(le,mid);cdq(mid+1,ri);
    sort(que+le,que+ri+1,cmp2);
    for(int i=le;i<=ri;++i)
    {
        if(que[i].id<=mid)add(que[i].r,que[i].cot);
        else que[i].sum+=query(0,que[i].r+1);
    }
    for(int i=le;i<=ri;++i)
    if(que[i].id<=mid)add(que[i].r,-que[i].cot);
}
void ac()
{
    sort(x+1,x+1+n,cmp1);
    for(int i=1;i<=n;++i)
    {
        if(x[i]!=x[i-1])que[++tot]=x[i],que[tot].id=tot;
        ++que[tot].cot;
    }
    cdq(1,tot);
    for(int i=1;i<=tot;++i)ans[que[i].sum+que[i].cot-1]+=que[i].cot;
    for(int i=0;i<n;++i)printf("%d\n",ans[i]);
}
int main()
{
    in();ac();
    return 0;
}
阅读更多
个人分类: cdq分治 线段树
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

不良信息举报

Luogu3810 三维偏序(陌上花开)

最多只允许输入30个字

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭