BZOJ 3262 陌上花开 “树套树”

27 篇文章 0 订阅

三维空间内求每个点比它3维都要大的点的个数。

第1维排序,第2维树状数组,第3维treap。

好像第1维排序就叫做降维了?

神tm吧一个数组开错大小老wa。。。

cdq分治好像挺好写

#include <cstdio>
#include <algorithm>
using namespace std;
int read() {
    int s=0,f=1;char ch=getchar();
    for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
    for(;'0'<=ch&&ch<='9';ch=getchar())s=s*10+ch-'0';
    return s*f;
}
const int N = 100005, M = 5000005;
int n, m, id;
int root[N * 2], ans[N], sum[N];
int s[M], l[M], r[M], v[M], w[M], rnk[M];
struct Flower {
    int a, b, c;
    friend bool operator < (const Flower &a, const Flower &b) {
        return (a.a==b.a)?((a.b==b.b)?(a.c<b.c):(a.b<b.b)):(a.a<b.a);
    }
} f[N];
void upd(int k){s[k]=s[l[k]]+s[r[k]]+w[k];}
void lrot(int &k){int t=r[k];r[k]=l[t];l[t]=k;upd(k);upd(t);k=t;}
void rrot(int &k){int t=l[k];l[k]=r[t];r[t]=k;upd(k);upd(t);k=t;}
void insert(int &k, int x) {
    if (!k) { k = ++id; rnk[k] = rand(); v[k] = x; s[k] = w[k] = 1; return; }
    s[k] ++;
    if     (x == v[k]) { w[k]++; return; }
    else if(x < v[k]) { insert(l[k], x); if(rnk[l[k]] < rnk[k]) rrot(k); }
    else              { insert(r[k], x); if(rnk[r[k]] < rnk[k]) lrot(k); }
}
int rank(int k, int x) {
    if (!k) return 0;
    if (x == v[k]) return s[l[k]] + w[k];
    else if(x < v[k]) return rank(l[k], x);
    else return s[l[k]] + w[k] + rank(r[k], x);
}
int query(int k, int x) {
    int ans = 0;
    for (k;  k; k -= k & -k) ans += rank(root[k], x);
    return ans;
}
void add(int k, int x) {
    for (k; k <= m; k += k & -k) insert(root[k], x);
}
int main() {
    n = read(); m = read();
    for (int i = 1; i <= n; i++)
        f[i].a = read(), f[i].b = read(), f[i].c = read();
    sort(f + 1, f + n + 1);
    for (int i = 1; i <= n; i ++) {
        if (f[i].a == f[i+1].a && f[i].b == f[i+1].b && f[i].c == f[i+1].c && i!=n)
            sum[i+1] += sum[i] + 1;
        else
            ans[query(f[i].b,f[i].c)]+=sum[i]+1;
        add(f[i].b, f[i].c);
    }
    for (int i = 0; i < n; i ++)
        printf("%d\n", ans[i]);
    return 0;
}


3262: 陌上花开

Time Limit: 20 Sec   Memory Limit: 256 MB
Submit: 544   Solved: 243
[ 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


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值