陌上花开

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分治)相关推荐

  1. BZOJ 3262 cdq分治 OR 树套树

    注意判断 三个条件都一样的-- (CDQ分治 其实并不是很难理解 只是想不到--) CDQ分治: //By SiriusRen #include <cstdio> #include < ...

  2. bzoj 3262: 陌上花开(cdq分治)

    3262: 陌上花开 Time Limit: 20 Sec  Memory Limit: 256 MB Submit: 2433  Solved: 1087 [Submit][Status][Disc ...

  3. 【BZOJ-3262】陌上花开 CDQ分治(3维偏序)

    3262: 陌上花开 Time Limit: 20 Sec  Memory Limit: 256 MB Submit: 1439  Solved: 648 [Submit][Status][Discu ...

  4. HYSBZ - 3295  动态逆序对 (cdq分治)

    F - 动态逆序对 HYSBZ - 3295 题目大意:给出一个序列有m个询问,每一个询问要求输出当前的逆序对数量后在原序列中删除该数字. 解题思路:如果将删除倒着做就变成了插入.没插入一个数字我们就 ...

  5. CDQ分治[陌上花开 ]

    关于CDQ,是大神陈丹琦写出来的算法,具体的看这个连接 https://www.cnblogs.com/lck-lck/p/9657753.html https://blog.csdn.net/wu_ ...

  6. BZOJ3262: 陌上花开(cdq分治)

    Time Limit: 20 Sec  Memory Limit: 256 MB Submit: 3627  Solved: 1705 [Submit][Status][Discuss] Descri ...

  7. 洛谷 - P3810 【模板】三维偏序(陌上花开)(CDQ分治套树状数组)

    题目链接:点击查看 题目大意:给出 n 个点,每个点有三个属性 a , b , c ,对于每个点 i 来说,求出有多少个 j 满足 a[ j ] <= a[ i ] && b[ ...

  8. 【教程】简易CDQ分治教程学习笔记

    前言 辣鸡蒟蒻__stdcall终于会CDQ分治啦!       CDQ分治是我们处理各类问题的重要武器.它的优势在于可以顶替复杂的高级数据结构,而且常数比较小:缺点在于必须离线操作. CDQ分治的基 ...

  9. cdq分治(bzoj 1176: [Balkan2007]Mokia bzoj 2683: 简单题)

    CDQ分治: 本质:对询问进行分治 优点:和莫队分块一样都属于技巧,关键时刻能免去复杂的数据结构,常数小 缺点:必须离线 参考:http://blog.csdn.net/hbhcy98/article ...

最新文章

  1. 某程序员吐槽:太尴尬!四年不见的前女友来公司面试,自己还是面试官!
  2. linux上安装pycharm
  3. java用重载实现获取元素的数据类型
  4. powerdesigner导出到mysql数据库
  5. ASP.Net开发新手常见问题备忘录
  6. 狂神说spring笔记
  7. 基于jsp+Spring+mybatis的SSM企业门户网站设计和实现
  8. Linux非root用户如何使用80端口启动程序
  9. truncate表和update 效率_SQL中Truncate的用法
  10. mysql时间加减运算
  11. AVOD阅读笔记(一):摘要+特征提取----Aggregate View Obeject Detection network
  12. 远程计算机ip记录怎么删除吗,远程桌面连接清除登陆过的IP地址
  13. Typora免费版官网下载
  14. Android-系统服务-ClipboardManager
  15. 星巴克中国咖啡创新产业园正式动工,追加项目总投资至近11亿元
  16. 8-25 26 veriloga语言
  17. 棋盘格自动生成器——四种格式(格雷码棋盘格、圆点、二维码棋盘格)
  18. 今日学习——冒泡排序
  19. MFC获取主机IP地址
  20. GameFramework篇:StarForce资源热更新讲解(二:具体操作步骤)

热门文章

  1. Order asynchronous mode
  2. Angular.js 页面里的按钮点击事件处理
  3. 关于安卓手机访问一些网站或者Fiori应用弹出安装证书的提示
  4. OpenFOAM中slip和noslip介绍(滑移条件无滑移条件)【翻译】
  5. java 安卓界面 可视化_Monkey可视化工具开发(android篇)
  6. js中在表格中增加一列的方法_Excel表格中需要提取一列内容末尾的数字,同事分分钟完成...
  7. mysql在linux下显示花_在Linux 中搭建 Mysql
  8. 笨方法python3_“笨方法”学Python3,习题 34 。
  9. javascript字典中添加数组_在javascript中合并两个字典数组
  10. antd 表格树如何展开_ant-design-pro protable 树形表格默认展开