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行,每行三个整数si, ci, mi (1 <= si, ci, mi <= K),表示第i朵花的属性

Output

包含N行,分别表示评级为0...N-1的每级花的数量。

Sample Input

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

Sample Output

3
1
3
0
1
0
1
0
0
1

HINT

1 <= N <= 100,000, 1 <= K <= 200,000

Source

  题目大意 三维偏序计数。

  首先偏序问题对于5维以下,通常有两种做法

  1)k-1层套树(我表示拒绝写这类程序,宁可写O(n2k)大暴力骗分,都不会去写这种"正解")

  2)CDQ分治 + (k - 2)层套树(比上面那种方法好多了)

  对于3维偏序,显然法2更优秀。可以参考上一道题(bzoj 1176)的做法。

  按c维第1关键字,m为第二关键字,s为第三关键字进行排序。

  对s进行CDQ分治。统计s在[l, mid]中的元素对[mid + 1, r]中的元素的贡献。用和上一道题同样的做法,将(c, m)看成一个点,左区间中的点看成修改操作,将点(c, m)的权值 + 1,右区间中的点看成查询一个子矩阵的点权和。然后做法一模一样。

  当l == r的时候就当成2维偏序问题,用树状数组水过。此时注意对于重复的判断。

Code

 /**
* bzoj
* Problem#3262
* Accepted
* Time:1628ms
* Memory:9012k
*/
#include <bits/stdc++.h>
using namespace std;
typedef bool boolean; typedef class Data {
public:
int val[];
int id; Data():val({, , }), id() { } friend boolean operator < (const Data& a, const Data &b) {
for(int i = ; i < ; i++)
if(a.val[i] != b.val[i])
return a.val[i] < b.val[i];
return a.val[] < b.val[];
} boolean operator == (Data b) {
return val[] == b.val[] && val[] == b.val[] && val[] == b.val[];
}
}Data; #define lowbit(x) ((x) & (-x)) typedef class IndexedTree {
public:
int s;
int *lis; IndexedTree():lis(NULL), s() { }
IndexedTree(int s):s(s) {
lis = new int[(s + )];
memset(lis, , sizeof(int) * (s + ));
} inline void add(int idx, int x) {
for(; idx <= s; idx += lowbit(idx))
lis[idx] += x;
} inline int getSum(int idx) {
int rt = ;
for(; idx; idx -= lowbit(idx))
rt += lis[idx];
return rt;
}
}IndexedTree; int n, K;
vector<Data> ds;
IndexedTree it;
int *scores;
int *cnts; inline void init() {
scanf("%d%d", &n, &K);
scores = new int[(n + )];
cnts = new int[(n + )];
memset(scores, , sizeof(int) * (n + ));
memset(cnts, , sizeof(int) * (n + ));
Data d;
for(int i = ; i < n; i++) {
for(int j = ; j < ; j++)
scanf("%d", &d.val[j]);
d.id = i;
ds.push_back(d);
}
} void CDQDividing(int l, int r, vector<Data> &q) {
if(q.empty()) return;
if(l == r) {
for(int i = , j; i < (signed)q.size(); i = j) {
it.add(q[i].val[], );
for(j = i + ; j < (signed)q.size() && q[j] == q[j - ]; j++)
it.add(q[j].val[], );
int c = it.getSum(q[i].val[]);
for(int k = i; k < j; k++)
scores[q[k].id] += c - ;
}
for(int i = ; i < (signed)q.size(); i++)
it.add(q[i].val[], -);
return;
} int mid = (l + r) >> ;
vector<Data> ql, qr;
for(int i = ; i < (signed)q.size(); i++) {
if(q[i].val[] <= mid)
it.add(q[i].val[], ), ql.push_back(q[i]);
else
scores[q[i].id] += it.getSum(q[i].val[]), qr.push_back(q[i]);
} for(int i = ; i < (signed)ql.size(); i++)
it.add(ql[i].val[], -); q.clear();
CDQDividing(l, mid, ql);
CDQDividing(mid + , r, qr);
} inline void solve() {
sort(ds.begin(), ds.end());
it = IndexedTree(K);
// for(int i = 0; i < n; i++)
// printf("%d %d %d\n", ds[i].val[0], ds[i].val[1], ds[i].val[2]);
CDQDividing(, K, ds);
for(int i = ; i < n; i++)
cnts[scores[i]]++;
for(int i = ; i < n; i++)
printf("%d\n", cnts[i]);
} int main() {
init();
solve();
return ;
}

bzoj 3262 陌上花开 - CDQ分治 - 树状数组的更多相关文章

  1. BZOJ 1176 Mokia CDQ分治+树状数组

    1176: [Balkan2007]Mokia Time Limit: 30 Sec  Memory Limit: 162 MBSubmit: 1854  Solved: 821[Submit][St ...

  2. 【bzoj3262】陌上花开 CDQ分治+树状数组

    题目描述 有n朵花,每朵花有三个属性:花形(s).颜色(c).气味(m),又三个整数表示.现要对每朵花评级,一朵花的级别是它拥有的美丽能超过的花的数量.定义一朵花A比另一朵花B要美丽,当且仅当Sa&g ...

  3. bzoj3262: 陌上花开(cdq分治+树状数组)

    3262: 陌上花开 题目:传送门 题解: %%%cdq分治 很强大的一个暴力...感觉比分块高级多了 这道题目就是一个十分经典的三维偏序的例题: 一维直接暴力排序x 二维用csq维护y 三维用树状数 ...

  4. [Bzoj3262]陌上花开(CDQ分治&&树状数组||树套树)

    题目链接 题目就是赤裸裸的三维偏序,所以用CDQ+树状数组可以比较轻松的解决,但是还是树套树好想QAQ CDQ+树状数组 #include<bits/stdc++.h> using nam ...

  5. BZOJ 2683 简单题 cdq分治+树状数组

    题意:链接 **方法:**cdq分治+树状数组 解析: 首先对于这道题,看了范围之后.二维的数据结构是显然不能过的.于是我们可能会考虑把一维排序之后还有一位上数据结构什么的,然而cdq分治却可以非常好 ...

  6. BZOJ_3262_陌上花开_CDQ分治+树状数组

    BZOJ_3262_陌上花开_CDQ分治+树状数组 Description 有n朵花,每朵花有三个属性:花形(s).颜色(c).气味(m),用三个整数表示. 现在要对每朵花评级,一朵花的级别是它拥有的 ...

  7. 【BZOJ4553】[Tjoi2016&Heoi2016]序列 cdq分治+树状数组

    [BZOJ4553][Tjoi2016&Heoi2016]序列 Description 佳媛姐姐过生日的时候,她的小伙伴从某宝上买了一个有趣的玩具送给他.玩具上有一个数列,数列中某些项的值可能 ...

  8. 【bzoj2225】[Spoj 2371]Another Longest Increasing CDQ分治+树状数组

    题目描述 给定N个数对(xi, yi),求最长上升子序列的长度.上升序列定义为{(xi, yi)}满足对i<j有xi<xj且yi<yj. 样例输入 8 1 3 3 2 1 1 4 5 ...

  9. LOJ3146 APIO2019路灯(cdq分治+树状数组)

    每个时刻都形成若干段满足段内任意两点可达.将其视为若干正方形.则查询相当于求历史上某点被正方形包含的时刻数量.并且注意到每个时刻只有O(1)个正方形出现或消失,那么求出每个矩形的出现时间和消失时间,就 ...

随机推荐

  1. JAVA_Stream_练习

    package airycode_java8.nice7; import airycode_java8.nice1.Employee; import org.junit.Test; import ja ...

  2. linux基本格式和常用目录命令一

    1: cd 绝对路径 2: cd 相对路径 名字开头 ./开头 ../开头 3: cd ~: 去到当前用户所在目录; 4: pwd获取当前的路径的绝对路径; 5: ls 与ls -l 6: cat 操 ...

  3. Yii Restful api认证

  4. html5-表单和input元素用法

    <!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8&qu ...

  5. C-Cow Sorting (置换群, 数学)

    Farmer John's N (1 ≤ N ≤ 10,000) cows are lined up to be milked in the evening. Each cow has a uniqu ...

  6. 第三方包源码maven 下载

    1,maven导包时候自动下载源码 在eclipse或者Myeclipse中 => window ==> preference ==> Maven ==> 勾选Download ...

  7. 接口作为方法的参数或返回值——List接口

    接口作为方法的参数或返回值,源码可知,List为一个接口,ArraryList是的它的实现类: 其中,addNames方法中,入参和返回值都List接口,入参是多态的,编译看左,运行看右(访问成员方法 ...

  8. 20165215 学习基础和c语言基础调查

    学习基础和c语言基础调查 <做中学>读后感与技能学习心得 读后感 Don't watch the clock. Do what it does. Keep going. 不要只看时钟,要效 ...

  9. Base64图片编码原理,base64图片工具介绍,图片在线转换Base64

    Base64图片编码原理,base64图片工具介绍,图片在线转换Base64 DataURI 允许在HTML文档中嵌入小文件,可以使用 img 标签或 CSS 嵌入转换后的 Base64 编码,减少  ...

  10. 远程服务调用RPC框架介绍,微服务架构介绍和RPC框架对比,dubbo、SpringClound对比

    远程服务调用RPC框架介绍,微服务架构介绍和RPC框架对比,dubbo.SpringClound对比 远程服务调用RPC框架介绍,RPC简单的来说就是像调用本地服务一样调用远程服务. 分布式RPC需要 ...