bzoj 3262 陌上花开 - CDQ分治 - 树状数组
Description
Input
Output
Sample Input
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
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分治 - 树状数组的更多相关文章
- BZOJ 1176 Mokia CDQ分治+树状数组
1176: [Balkan2007]Mokia Time Limit: 30 Sec Memory Limit: 162 MBSubmit: 1854 Solved: 821[Submit][St ...
- 【bzoj3262】陌上花开 CDQ分治+树状数组
题目描述 有n朵花,每朵花有三个属性:花形(s).颜色(c).气味(m),又三个整数表示.现要对每朵花评级,一朵花的级别是它拥有的美丽能超过的花的数量.定义一朵花A比另一朵花B要美丽,当且仅当Sa&g ...
- bzoj3262: 陌上花开(cdq分治+树状数组)
3262: 陌上花开 题目:传送门 题解: %%%cdq分治 很强大的一个暴力...感觉比分块高级多了 这道题目就是一个十分经典的三维偏序的例题: 一维直接暴力排序x 二维用csq维护y 三维用树状数 ...
- [Bzoj3262]陌上花开(CDQ分治&&树状数组||树套树)
题目链接 题目就是赤裸裸的三维偏序,所以用CDQ+树状数组可以比较轻松的解决,但是还是树套树好想QAQ CDQ+树状数组 #include<bits/stdc++.h> using nam ...
- BZOJ 2683 简单题 cdq分治+树状数组
题意:链接 **方法:**cdq分治+树状数组 解析: 首先对于这道题,看了范围之后.二维的数据结构是显然不能过的.于是我们可能会考虑把一维排序之后还有一位上数据结构什么的,然而cdq分治却可以非常好 ...
- BZOJ_3262_陌上花开_CDQ分治+树状数组
BZOJ_3262_陌上花开_CDQ分治+树状数组 Description 有n朵花,每朵花有三个属性:花形(s).颜色(c).气味(m),用三个整数表示. 现在要对每朵花评级,一朵花的级别是它拥有的 ...
- 【BZOJ4553】[Tjoi2016&Heoi2016]序列 cdq分治+树状数组
[BZOJ4553][Tjoi2016&Heoi2016]序列 Description 佳媛姐姐过生日的时候,她的小伙伴从某宝上买了一个有趣的玩具送给他.玩具上有一个数列,数列中某些项的值可能 ...
- 【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 ...
- LOJ3146 APIO2019路灯(cdq分治+树状数组)
每个时刻都形成若干段满足段内任意两点可达.将其视为若干正方形.则查询相当于求历史上某点被正方形包含的时刻数量.并且注意到每个时刻只有O(1)个正方形出现或消失,那么求出每个矩形的出现时间和消失时间,就 ...
随机推荐
- 等比数列二分求和(logn复杂度)
看完这个之后,感觉数学简直太厉害了 转载自:http://blog.csdn.net/acdreamers/article/details/7851144 今天我们学习如何有效地求表达式的值.对于这个 ...
- 前端forEach在Array、map、set中的使用,weakset,weakmap
数组: var s = ['a','b','c']; s.forEach(function(ele,index,array){ console.log(ele); }); Map: var map = ...
- Opcode是啥以及如何使用好Opcache
转载 https://www.zybuluo.com/phper/note/1016714 啥是Opcode? 我们在日常的PHP开发过程中,应该经常会听见Opcache这个词,那么啥是Opcode ...
- 本地文件直接访问html,document.cookie总是显示空字符串
当file:///E:/browser.html访问时,我们设置document.cookie,读取时一直会显示空字符串! 而开一下Apache时:localhost/browser.html或者12 ...
- Codeforces Round #323
div1 C 这题的是给了一个无限循环的子数组,问有多少个 (l,s)l代表起点s代表长度的循环串,使得所有的在原串中的每位都小于等于另外这个串(l<=n,1<=s<n) 像这样,我 ...
- 模拟QQ登录
2018-10-28 15:54:38 开始写 import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.bor ...
- PCH 文件 和 ProjectName-Bridging-Header 配置
1.简介 PCH文件是Xcode编程中全局引用共享的文件.可以在这里引入头文件或者宏定义来方便程序中多个文件访问. 2.PCH文件创建 打开工程 New File… -> iOS Other - ...
- skynet对Windows环境支持的版本:Windows版skynet
https://github.com/sanikoyes/skynet.git Skynet Skynet is a lightweight online game framework, and it ...
- QString 与 string转换
[1]QString 转换为string QString qString("好好学习天天向上"); std::string stdString = qString.toStdStr ...
- STL容器之list
[1]list简介 实质上,list容器就是一个双向链表,可以高效地进行插入.删除操作. [2]list链表常用方法 (1)构造.赋值.清空.删除.插入.判空等 应用示例代码如下: #include ...