BZOJ 3262 陌上花开
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
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
1
3
0
1
0
1
0
0
1
题意 : 三维偏序裸题
代码示例 :
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn = 1e5+5;
typedef pair<int, int>P;
#define fi first
#define se second
int n, m;
struct node
{
int x, y, z;
int num, cnt; // num等级 , cnt 数量
node(int _x=0, int _y=0, int _z=0):x(_x), y(_y), z(_z){}
bool operator< (const node &v)const{
if (x == v.x && y == v.y) return z < v.z;
else if (x == v.x) return y < v.y;
return x < v.x;
}
}arr[maxn], f[maxn];
int k = 1;
int c[maxn*2];
int lowbit(int x){return x&(-x); }
void add(int p, int num){
for(int i = p; i <= m; i += lowbit(i)) c[i] += num;
}
int query(int p){
int sum = 0;
for(int i = p; i ; i -= lowbit(i)){
sum += c[i];
}
return sum;
}
void CDQ(int l, int r){
if (l == r) return;
int mid = (l+r)>>1;
CDQ(l, mid);
CDQ(mid+1, r);
int p1 = l, p2 = mid+1;
int num = 0;
for(int i = l; i <= r; i++){
if (p1<=mid && (p2 > r || arr[p1].y <= arr[p2].y)){
add(arr[p1].z, arr[p1].cnt);
f[num++] = arr[p1++];
}
else {
int num2 = query(arr[p2].z);
arr[p2].num += num2;
f[num++] = arr[p2++];
}
}
num = 0;
for(int i = l; i <= r; i++) {
if (i <= mid) add(arr[i].z, -arr[i].cnt);
arr[i] = f[num++];
}
}
int ans[maxn];
int main () {
int x, y, z;
cin >> n >> m;
for(int i = 1; i <= n; i++){
scanf("%d%d%d", &x, &y, &z);
arr[i] = node(x, y, z);
arr[i].num = arr[i].cnt = 1;
}
sort(arr+1, arr+1+n);
for(int i = 2; i <= n; i++){
if (arr[i].x == arr[k].x && arr[i].y == arr[k].y && arr[i].z == arr[k].z){
arr[k].num++;
arr[k].cnt++;
}
else arr[++k] = arr[i];
}
CDQ(1, k);
for(int i = 1; i <= k; i++){
ans[arr[i].num-1] += arr[i].cnt;
}
for(int i = 0; i < n; i++) printf("%d\n", ans[i]);
return 0;
}
东北日出西边雨 道是无情却有情

浙公网安备 33010602011771号