3262: 陌上花开

来源:互联网 发布:算日子的软件 编辑:程序博客网 时间:2024/04/29 03:10

3262: 陌上花开

Time Limit: 20 Sec  Memory Limit: 256 MB
Submit: 1423  Solved: 640
[Submit][Status][Discuss]

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

树套树 CDQ分治

[Submit][Status][Discuss]



排序一维

树状数组一维

线段树一维

#include<iostream>#include<cstdio>#include<algorithm>using namespace std;const int maxn = 2E5 + 20;const int T = 100;struct data{int a,b,c,Num;data(){}data(int a,int b,int c,int Num): a(a),b(b),c(c),Num(Num){}bool operator < (const data &B) const {return a < B.a;}}f[maxn];int n,m,cnt,Root[maxn],lc[maxn*T],rc[maxn*T],c[maxn*T],rank[maxn],ans[maxn];int Getlc(int o) {return lc[o]?lc[o]:lc[o] = ++cnt;}int Getrc(int o) {return rc[o]?rc[o]:rc[o] = ++cnt;}int Query(int o,int l,int r,int ql,int qr){if (ql <= l && r <= qr) return c[o];if (!o) return 0;int mid = (l + r) >> 1,ret = 0;if (ql <= mid) ret += Query(lc[o],l,mid,ql,qr);if (qr > mid) ret += Query(rc[o],mid + 1,r,ql,qr);return ret;}void Insert(int o,int l,int r,int pos){if (l == r) {++c[o];return;}int mid = (l + r) >> 1;if (pos <= mid) Insert(Getlc(o),l,mid,pos);else Insert(Getrc(o),mid + 1,r,pos);c[o] = c[lc[o]] + c[rc[o]];}int getint(){char ch = getchar();int ret = 0;while (ch < '0' || '9' < ch) ch = getchar();while ('0' <= ch && ch <= '9')ret = ret*10 + ch - '0',ch = getchar();return ret;}int main(){#ifdef DMCfreopen("DMC.txt","r",stdin);#endifn = getint(); m = getint();for (int i = 1; i <= n; i++) {int a,b,c;a = getint();b = getint();c = getint();f[i] = data(a,b,c,i);}sort(f + 1,f + n + 1);int L = 1;for (int i = 1; i <= n + 1; i++) {if (f[i].a != f[i-1].a && i > 1) {for (int j = L; j < i; j++) {for (int l = f[j].b; l > 0; l -= l&-l)rank[f[j].Num] += Query(Root[l],1,m,1,f[j].c);--rank[f[j].Num];}L = i;}if (i == n + 1) break;for (int j = f[i].b; j <= m; j += j&-j) {if (!Root[j]) Root[j] = ++cnt;Insert(Root[j],1,m,f[i].c);}}for (int i = 1; i <= n; i++) ++ans[rank[i]];for (int i = 0; i < n; i++)printf("%d\n",ans[i]);return 0;}

0 0
原创粉丝点击