陌上花开 HYSBZ - 3262 (CDQ分治)
陌上花開
HYSBZ - 3262
有n朵花,每朵花有三個(gè)屬性:花形(s)、顏色(c)、氣味(m),用三個(gè)整數(shù)表示。
現(xiàn)在要對(duì)每朵花評(píng)級(jí),一朵花的級(jí)別是它擁有的美麗能超過的花的數(shù)量。
定義一朵花A比另一朵花B要美麗,當(dāng)且僅Sa>=Sb,Ca>=Cb,Ma>=Mb。
顯然,兩朵花可能有同樣的屬性。需要統(tǒng)計(jì)出評(píng)出每個(gè)等級(jí)的花的數(shù)量。
Input
第一行為N,K (1 <= N <= 100,000, 1 <= K <= 200,000 ), 分別表示花的數(shù)量和最大屬性值。
以下N行,每行三個(gè)整數(shù)si, ci, mi (1 <= si, ci, mi <= K),表示第i朵花的屬性
Output
包含N行,分別表示評(píng)級(jí)為0...N-1的每級(jí)花的數(shù)量。
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分治解決三維偏序的模板題。
推薦去這里學(xué)習(xí):https://oi-wiki.org/misc/cdq-divide/
我寫了兩個(gè)版本,分別是第二維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);// 第三維度加入到樹樁數(shù)組中pl++;}b[pr].ans += ask(b[pr].z);// 樹樁數(shù)組求前綴和的形式來求也滿足第三維的偏序個(gè)數(shù)pr++;}repd(i, l, pl - 1) {add(b[i].z, -b[i].cnt);// 清空樹樁數(shù)組。} } 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++;// 把三個(gè)維度都相同的縮在一起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++;// 把三個(gè)維度都相同的縮在一起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';}} }轉(zhuǎn)載于:https://www.cnblogs.com/qieqiemin/p/11552647.html
總結(jié)
以上是生活随笔為你收集整理的陌上花开 HYSBZ - 3262 (CDQ分治)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 在Mono 2.8上部署ASP.NET
- 下一篇: 设计模式学习笔记五——Prototype