陌上花开 HYSBZ - 3262 (CDQ分治)
陌上花开
HYSBZ - 3262
有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
思路:
CDQ分治解决三维偏序的模板题。
推荐去这里学习:https://oi-wiki.org/misc/cdq-divide/
我写了两个版本,分别是第二维sort和归并排序。
代码(sort版本):
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <vector>
#include <iomanip>
#define ALL(x) (x).begin(), (x).end()
#define sz(a) int(a.size())
#define rep(i,x,n) for(int i=x;i<n;i++)
#define repd(i,x,n) for(int i=x;i<=n;i++)
#define pii pair<int,int>
#define pll pair<long long ,long long>
#define gbtb ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define MS0(X) memset((X), 0, sizeof((X)))
#define MSC0(X) memset((X), '\0', sizeof((X)))
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define eps 1e-6
#define gg(x) getInt(&x)
#define chu(x) cout<<"["<<#x<<" "<<(x)<<"]"<<endl
#define du3(a,b,c) scanf("%d %d %d",&(a),&(b),&(c))
#define du2(a,b) scanf("%d %d",&(a),&(b))
#define du1(a) scanf("%d",&(a));
using namespace std;
typedef long long ll;
ll gcd(ll a, ll b) {return b ? gcd(b, a % b) : a;}
ll lcm(ll a, ll b) {return a / gcd(a, b) * b;}
ll powmod(ll a, ll b, ll MOD) {a %= MOD; if (a == 0ll) {return 0ll;} ll ans = 1; while (b) {if (b & 1) {ans = ans * a % MOD;} a = a * a % MOD; b >>= 1;} return ans;}
void Pv(const vector<int> &V) {int Len = sz(V); for (int i = 0; i < Len; ++i) {printf("%d", V[i] ); if (i != Len - 1) {printf(" ");} else {printf("\n");}}}
void Pvl(const vector<ll> &V) {int Len = sz(V); for (int i = 0; i < Len; ++i) {printf("%lld", V[i] ); if (i != Len - 1) {printf(" ");} else {printf("\n");}}}inline void getInt(int *p);
const int maxn = 1000010;
const int inf = 0x3f3f3f3f;
/*** TEMPLATE CODE * * STARTS HERE ***/
struct node {int x, y, z;int cnt;int ans;
} a[maxn];
node b[maxn];
int Ans[maxn];
bool cmpx(node aa, node bb)
{if (aa.x != bb.x) {return aa.x < bb.x;} else if (aa.y != bb.y) {return aa.y < bb.y;} else {return aa.z < bb.z;}
}
bool cmpy(node aa, node bb)
{if (aa.y != bb.y) {return aa.y < bb.y;} else {return aa.z < bb.z;}
}
int n, k;
int tree[maxn];
int lowbit(int x)
{return -x & x;
}
void add(int x, int v)
{while (x < maxn) {tree[x] += v;x += lowbit(x);}
}
int ask(int x)
{int res = 0;while (x) {res += tree[x];x -= lowbit(x);}return res;
}
void CDQ(int l, int r)
{if (l == r) {return ;}int mid = (l + r) >> 1;CDQ(l, mid);CDQ(mid + 1, r);// 排序第二维度sort(b + l, b + mid + 1, cmpy);sort(b + mid + 1, b + r + 1, cmpy);int pl = l;int pr = mid + 1;while (pr <= r) {while (pl <= mid && b[pl].y <= b[pr].y) {add(b[pl].z, b[pl].cnt);// 第三维度加入到树桩数组中pl++;}b[pr].ans += ask(b[pr].z);// 树桩数组求前缀和的形式来求也满足第三维的偏序个数pr++;}repd(i, l, pl - 1) {add(b[i].z, -b[i].cnt);// 清空树桩数组。}
}
int main()
{//freopen("D:\\code\\text\\input.txt","r",stdin);//freopen("D:\\code\\text\\output.txt","w",stdout);du2(n, k);repd(i, 1, n) {du3(a[i].x, a[i].y, a[i].z);}int m = 0;int cnt = 0;sort(a + 1, a + 1 + n, cmpx);// 排序第一维度repd(i, 1, n) {cnt++;// 把三个维度都相同的缩在一起if (a[i].x != a[i + 1].x || a[i].y != a[i + 1].y || a[i].z != a[i + 1].z) {b[++m] = a[i];b[m].cnt = cnt;cnt = 0;}}CDQ(1, m);repd(i, 1, m) {Ans[b[i].ans + b[i].cnt - 1] += b[i].cnt;}repd(i, 0, n - 1) {printf("%d\n", Ans[i] );}return 0;
}inline void getInt(int *p)
{char ch;do {ch = getchar();} while (ch == ' ' || ch == '\n');if (ch == '-') {*p = -(getchar() - '0');while ((ch = getchar()) >= '0' && ch <= '9') {*p = *p * 10 - ch + '0';}} else {*p = ch - '0';while ((ch = getchar()) >= '0' && ch <= '9') {*p = *p * 10 + ch - '0';}}
}
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <vector>
#include <iomanip>
#define ALL(x) (x).begin(), (x).end()
#define sz(a) int(a.size())
#define rep(i,x,n) for(int i=x;i<n;i++)
#define repd(i,x,n) for(int i=x;i<=n;i++)
#define pii pair<int,int>
#define pll pair<long long ,long long>
#define gbtb ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define MS0(X) memset((X), 0, sizeof((X)))
#define MSC0(X) memset((X), '\0', sizeof((X)))
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define eps 1e-6
#define gg(x) getInt(&x)
#define chu(x) cout<<"["<<#x<<" "<<(x)<<"]"<<endl
#define du3(a,b,c) scanf("%d %d %d",&(a),&(b),&(c))
#define du2(a,b) scanf("%d %d",&(a),&(b))
#define du1(a) scanf("%d",&(a));
using namespace std;
typedef long long ll;
ll gcd(ll a, ll b) {return b ? gcd(b, a % b) : a;}
ll lcm(ll a, ll b) {return a / gcd(a, b) * b;}
ll powmod(ll a, ll b, ll MOD) {a %= MOD; if (a == 0ll) {return 0ll;} ll ans = 1; while (b) {if (b & 1) {ans = ans * a % MOD;} a = a * a % MOD; b >>= 1;} return ans;}
void Pv(const vector<int> &V) {int Len = sz(V); for (int i = 0; i < Len; ++i) {printf("%d", V[i] ); if (i != Len - 1) {printf(" ");} else {printf("\n");}}}
void Pvl(const vector<ll> &V) {int Len = sz(V); for (int i = 0; i < Len; ++i) {printf("%lld", V[i] ); if (i != Len - 1) {printf(" ");} else {printf("\n");}}}inline void getInt(int *p);
const int maxn = 1000010;
const int inf = 0x3f3f3f3f;
/*** TEMPLATE CODE * * STARTS HERE ***/
struct node {int x, y, z;int cnt;int ans;
} a[maxn];
node b[maxn];
node c[maxn];
int Ans[maxn];
bool cmpx(node aa, node bb)
{if (aa.x != bb.x) {return aa.x < bb.x;} else if (aa.y != bb.y) {return aa.y < bb.y;} else {return aa.z < bb.z;}
}
bool cmpy(node aa, node bb)
{if (aa.y != bb.y) {return aa.y < bb.y;} else {return aa.z < bb.z;}
}
int n, k;
int tree[maxn];
int lowbit(int x)
{return -x & x;
}
void add(int x, int v)
{while (x < maxn) {tree[x] += v;x += lowbit(x);}
}
int ask(int x)
{int res = 0;while (x) {res += tree[x];x -= lowbit(x);}return res;
}
void CDQ(int l, int r)
{if (l == r) {return ;}int mid = (l + r) >> 1;CDQ(l, mid);CDQ(mid + 1, r);int ql = l;int qr = mid + 1;repd(i, l, r) {if (qr > r || (ql <= mid && b[ql].y <= b[qr].y)) {add(b[ql].z, b[ql].cnt);c[i] = b[ql++];} else {b[qr].ans += ask(b[qr].z);c[i] = b[qr++];}}ql = l;qr = mid + 1;repd(i, l, r) {if (qr > r || (ql <= mid && b[ql].y <= b[qr].y)) {add(b[ql].z, -b[ql].cnt);ql++;} else {qr++;}}repd(i, l, r) {b[i] = c[i];}}
int main()
{//freopen("D:\\code\\text\\input.txt","r",stdin);//freopen("D:\\code\\text\\output.txt","w",stdout);du2(n, k);repd(i, 1, n) {du3(a[i].x, a[i].y, a[i].z);}int m = 0;int cnt = 0;sort(a + 1, a + 1 + n, cmpx);// 排序第一维度repd(i, 1, n) {cnt++;// 把三个维度都相同的缩在一起if (a[i].x != a[i + 1].x || a[i].y != a[i + 1].y || a[i].z != a[i + 1].z) {b[++m] = a[i];b[m].cnt = cnt;cnt = 0;}}CDQ(1, m);repd(i, 1, m) {Ans[b[i].ans + b[i].cnt - 1] += b[i].cnt;}repd(i, 0, n - 1) {printf("%d\n", Ans[i] );}return 0;
}inline void getInt(int *p)
{char ch;do {ch = getchar();} while (ch == ' ' || ch == '\n');if (ch == '-') {*p = -(getchar() - '0');while ((ch = getchar()) >= '0' && ch <= '9') {*p = *p * 10 - ch + '0';}} else {*p = ch - '0';while ((ch = getchar()) >= '0' && ch <= '9') {*p = *p * 10 + ch - '0';}}
}
转载于:https://www.cnblogs.com/qieqiemin/p/11552647.html
陌上花开 HYSBZ - 3262 (CDQ分治)相关推荐
- BZOJ 3262 cdq分治 OR 树套树
注意判断 三个条件都一样的-- (CDQ分治 其实并不是很难理解 只是想不到--) CDQ分治: //By SiriusRen #include <cstdio> #include < ...
- bzoj 3262: 陌上花开(cdq分治)
3262: 陌上花开 Time Limit: 20 Sec Memory Limit: 256 MB Submit: 2433 Solved: 1087 [Submit][Status][Disc ...
- 【BZOJ-3262】陌上花开 CDQ分治(3维偏序)
3262: 陌上花开 Time Limit: 20 Sec Memory Limit: 256 MB Submit: 1439 Solved: 648 [Submit][Status][Discu ...
- HYSBZ - 3295 动态逆序对 (cdq分治)
F - 动态逆序对 HYSBZ - 3295 题目大意:给出一个序列有m个询问,每一个询问要求输出当前的逆序对数量后在原序列中删除该数字. 解题思路:如果将删除倒着做就变成了插入.没插入一个数字我们就 ...
- CDQ分治[陌上花开 ]
关于CDQ,是大神陈丹琦写出来的算法,具体的看这个连接 https://www.cnblogs.com/lck-lck/p/9657753.html https://blog.csdn.net/wu_ ...
- BZOJ3262: 陌上花开(cdq分治)
Time Limit: 20 Sec Memory Limit: 256 MB Submit: 3627 Solved: 1705 [Submit][Status][Discuss] Descri ...
- 洛谷 - P3810 【模板】三维偏序(陌上花开)(CDQ分治套树状数组)
题目链接:点击查看 题目大意:给出 n 个点,每个点有三个属性 a , b , c ,对于每个点 i 来说,求出有多少个 j 满足 a[ j ] <= a[ i ] && b[ ...
- 【教程】简易CDQ分治教程学习笔记
前言 辣鸡蒟蒻__stdcall终于会CDQ分治啦! CDQ分治是我们处理各类问题的重要武器.它的优势在于可以顶替复杂的高级数据结构,而且常数比较小:缺点在于必须离线操作. CDQ分治的基 ...
- cdq分治(bzoj 1176: [Balkan2007]Mokia bzoj 2683: 简单题)
CDQ分治: 本质:对询问进行分治 优点:和莫队分块一样都属于技巧,关键时刻能免去复杂的数据结构,常数小 缺点:必须离线 参考:http://blog.csdn.net/hbhcy98/article ...
最新文章
- 某程序员吐槽:太尴尬!四年不见的前女友来公司面试,自己还是面试官!
- linux上安装pycharm
- java用重载实现获取元素的数据类型
- powerdesigner导出到mysql数据库
- ASP.Net开发新手常见问题备忘录
- 狂神说spring笔记
- 基于jsp+Spring+mybatis的SSM企业门户网站设计和实现
- Linux非root用户如何使用80端口启动程序
- truncate表和update 效率_SQL中Truncate的用法
- mysql时间加减运算
- AVOD阅读笔记(一):摘要+特征提取----Aggregate View Obeject Detection network
- 远程计算机ip记录怎么删除吗,远程桌面连接清除登陆过的IP地址
- Typora免费版官网下载
- Android-系统服务-ClipboardManager
- 星巴克中国咖啡创新产业园正式动工,追加项目总投资至近11亿元
- 8-25 26 veriloga语言
- 棋盘格自动生成器——四种格式(格雷码棋盘格、圆点、二维码棋盘格)
- 今日学习——冒泡排序
- MFC获取主机IP地址
- GameFramework篇:StarForce资源热更新讲解(二:具体操作步骤)
热门文章
- Order asynchronous mode
- Angular.js 页面里的按钮点击事件处理
- 关于安卓手机访问一些网站或者Fiori应用弹出安装证书的提示
- OpenFOAM中slip和noslip介绍(滑移条件无滑移条件)【翻译】
- java 安卓界面 可视化_Monkey可视化工具开发(android篇)
- js中在表格中增加一列的方法_Excel表格中需要提取一列内容末尾的数字,同事分分钟完成...
- mysql在linux下显示花_在Linux 中搭建 Mysql
- 笨方法python3_“笨方法”学Python3,习题 34 。
- javascript字典中添加数组_在javascript中合并两个字典数组
- antd 表格树如何展开_ant-design-pro protable 树形表格默认展开