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

题目背景

这是一道模板题

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

题目描述

有 nn 个元素,第 ii 个元素有 a_iai?、b_ibi?、c_ici? 三个属性,设 f(i)f(i) 表示满足 a_j \leq a_iaj?≤ai? 且 b_j \leq b_ibj?≤bi? 且 c_j \leq c_icj?≤ci? 的 jj 的数量。

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

输入输出格式

输入格式:

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

之后 nn 行,每行三个整数 a_iai?、b_ibi?、c_ici?,分别表示三个属性值。

输出格式:

输出 nn 行,第 d + 1d+1 行表示 f(i) = df(i)=d 的 ii 的数量。

输入输出样例

输入样例#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

说明

1 \leq n \leq 100000, 1 \leq k \leq 2000001≤n≤100000,1≤k≤200000

//Pro:P3810 【模板】三维偏序(陌上花开)

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;

inline int read()
{
    char c=getchar();int num=0;
    for(;!isdigit(c);c=getchar());
    for(;isdigit(c);c=getchar())
        num=num*10+c-‘0‘;
    return num;
}

const int N=1e5+5;

int n,k;

struct THI
{
    int a,b,c,w,ans;
}thi[N],ele[N];
int m;

bool cmp1(THI A,THI B)
{
    return A.a==B.a?(A.b==B.b?A.c<B.c:A.b<B.b):A.a<B.a;
}

bool cmp2(THI A,THI B)
{
    return A.b==B.b?A.c<B.c:A.b<B.b;
}

#define lowbit(x) x&(-x)
int bit[N<<1],bound;

inline void add(int x,int val)
{
    for(;x<=k;x+=lowbit(x))
        bit[x]+=val;
}

inline int query(int x)
{
    int res=0;
    for(;x;x-=lowbit(x))
        res+=bit[x];
    return res;
}

void divide(int l,int r)
{
    if(l>=r)
        return;
    int mid=(l+r)>>1;
    divide(l,mid),divide(mid+1,r);
    sort(ele+l,ele+mid+1,cmp2);
    sort(ele+mid+1,ele+r+1,cmp2);
    int i=l,j=mid+1;
    for(;j<=r;++j)
    {
        while(ele[i].b<=ele[j].b&&i<=mid)
            add(ele[i].c,ele[i].w),++i;
        ele[j].ans+=query(ele[j].c);
    }
    for(j=l;j<i;++j)
        add(ele[j].c,-ele[j].w);
}

int ans[N];
int main()
{
    n=read(),k=read();
    for(int i=1;i<=n;++i)
        thi[i].a=read(),thi[i].b=read(),thi[i].c=read();
    sort(thi+1,thi+n+1,cmp1);
    for(int i=1,cnt=0;i<=n;++i)
    {
        ++cnt;
        if(thi[i].a!=thi[i+1].a||thi[i].b!=thi[i+1].b||thi[i].c!=thi[i+1].c)
        {
            ele[++m]=thi[i];
            ele[m].w=cnt,
            cnt=0;
        }
    }
    divide(1,m);
    for(int i=1;i<=m;++i)
        ans[ele[i].ans+ele[i].w-1]+=ele[i].w;
    for(int i=0;i<n;++i)
        printf("%d\n",ans[i]);
    return 0;
}

原文地址:https://www.cnblogs.com/lovewhy/p/9633897.html

时间: 2024-08-03 04:35:59

P3810 【模板】三维偏序(陌上花开)的相关文章

[模板] 三维偏序 - 树套树,线段树

#include <bits/stdc++.h> using namespace std; const int N = 2e+7 + 5; struct Pt { int a, b, c; int id; bool operator<(const Pt &x) const { return a < x.a; } } p[N]; map<int, int> ma, mb, mc; int aa[N], ab[N], ac[N]; int ida, idb, idc

P3810 -三维偏序(陌上花开)cdq-分治

P3810 [模板]三维偏序(陌上花开) 思路 :按照 1维排序 二维 分治三维树状数组维护 #include<bits/stdc++.h> using namespace std; #define maxn 234567 int n,k,id,s,tree[maxn*2],tong[maxn]; struct node { int a,b,c,ans,w; node() { ans=0; w=0; } } data[maxn]; bool cp1(node x,node y) { if(x.

BZOJ3262/洛谷P3810 陌上花开 CDQ分治 三维偏序 树状数组

原文链接http://www.cnblogs.com/zhouzhendong/p/8672131.html 题目传送门 - BZOJ3262 题目传送门 - 落谷P3810 题意 有$n$个元素,第$i$个元素有$a_i$.$b_i$.$c_i$三个属性,设$f(i)$表示满足$a_j\leq a_i$且$b_j\leq b_i$且$c_j\leq c_i$的$j$的数量.对于$d\in [0,n)$,求$f(i)=d$的数量. $n\leq 100000,max\{a_i,b_i,c_i|i

题解-luogu P3810三维偏序(陌上花开)

\(\rm三维偏序\) \(\rm一.定义:序列上每个点有三个权值~(x,y,z)~,求有多少个点对~(a,b)~同时满足~a_x \le b_x~,~a_y \le b_y~,~a_z \le b_z~\) \(\rm二.解法:~cdq~分治\) \(\rm\qquad首先,我们思考一下二维偏序的解法\) \(\rm\qquad\qquad我们先对整个序列按照~x~排一遍序,那么我们就已经解决了一个维度\) \(\rm\qquad\qquad即目前序列中所有后面的点的~x~值一定比前面的点小\

P2433 - 【BZOJ 3262三维偏序】陌上花开------三维偏序

P2433 - [BZOJ 3262三维偏序]陌上花开 Description 有n朵花,每朵花有三个属性:花形(s).颜色(c).气味(m),又三个整数表示.现要对每朵花评级,一朵花的级别是它拥有的美丽能超过的花的数量. 定义一朵花A比另一朵花B要美丽,当且仅当Sa>=Sb,Ca>=Cb,Ma>=Mb.显然,两朵花可能有同样的属性.需要统计出评出每个等级的花的数量. Input 第一行为N,K (1 <= N <= 100,000, 1 <= K <= 200,

三维偏序(陌上花开)

三维偏序(陌上花开) 有n个元素,第i个元素有\(a_i\),\(b_i\),\(c_i\)三个属性,设\(f(i)\)表示满足\(a_j\le a_i\)且\(b_j\le b_i\)且\(c_j\le c_i\)的j的数量.对于\(d\in[0, n)\),求\(f(i)=d\)的数量. 偏序关系,意思是并不是任意两个元素之间都有关系.以前在机房里天天听到"偏序""cdq",也知道偏序问题要用cdq分治来做.现在终于会辣! 显然,我们处理的是三元组之间的关系,并

BZOJ 3262: 陌上花开 [CDQ分治 三维偏序]

Description 有n朵花,每朵花有三个属性:花形(s).颜色(c).气味(m),又三个整数表示.现要对每朵花评级,一朵花的级别是它拥有的美丽能超过的花的数量.定义一朵花A比另一朵花B要美丽,当且仅当Sa>=Sb,Ca>=Cb,Ma>=Mb.显然,两朵花可能有同样的属性.需要统计出评出每个等级的花的数量. Input 第一行为N,K (1 <= N <= 100,000, 1 <= K <= 200,000 ), 分别表示花的数量和最大属性值. 以下N行,每

【三维偏序】【分块】bzoj3262 陌上花开

裸的三维偏序. 对x坐标排序,y.z坐标分块.复杂度O(n*sqrt(n*log(n))).代码很短. 1 #include<cstdio> 2 #include<cmath> 3 #include<algorithm> 4 #include<vector> 5 using namespace std; 6 struct Point{int x,y,z,num;void Read(){scanf("%d%d%d",&x,&

HDU 5618:Jam&#39;s problem again(CDQ分治+树状数组处理三维偏序)

http://acm.hdu.edu.cn/showproblem.php?pid=5618 题意:-- 思路:和NEUOJ那题一样的.重新写了遍理解了一下,算作处理三维偏序的模板了. 1 #include <cstdio> 2 #include <algorithm> 3 #include <iostream> 4 #include <cstring> 5 using namespace std; 6 #define INF 0x3f3f3f3f 7 #d