zoukankan      html  css  js  c++  java
  • 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

    Sample Output

    3
    1
    3
    0
    1
    0
    1
    0
    0
    1
     
    思路:
    看上去像很裸的cdq分治,其实就是非常裸的cdq分治,不过需要注意他相同的也算比他小的,这道题有三个维度,我们将第一个维度排个序,当作他们输入的时间,第二个维度用cdq分治去降维,第三个维度直接扔到树状数组上就好了
    当出现重复的点时,设有k个相同的点,那么按照插入的顺序相同的点中只有最后面的那个点的值是对的,前面的相同的点的值依此少1,那么我们就预处理一下,对于相同的点从后到前累加1,也就是原先那些相同的点离正确的值分别c差 k,k-1,k-2,...0,那么我们给他们的初始值依此加上  k,k-1,k-2,....,0,这样就可以得到正确的值了。
     
    #include<bits/stdc++.h>
    using namespace std;
    
    const int M = 1e5 + 10;
    
    int c[M<<2],n,ans[M],mx;
    
    struct node{
        int t,x,y;
        int id,ans;
    }a[M];
    node q[M];
    
    bool cmp(node a,node b){
        return (a.t<b.t)||(a.t==b.t&&(a.x<b.x||(a.x==b.x&&a.y<b.y)));
    }
    
    void add(int x,int val){
        while(x <= mx){
            c[x] += val;
            x += x&(-x);
        }
    }
    
    int getsum(int x){
        int sum = 0;
        while(x > 0){
            sum += c[x];
            x -= x&(-x);
        }
        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 L = l,R = mid + 1;
        for(int i = l;i <= r;i ++){
            if(L<=mid&&(R>r||a[L].x<=a[R].x)) q[i] = a[L++];
            else q[i] = a[R++];
        }
        for(int i = l;i <= r;i ++) a[i] = q[i];
        for(int i = l;i <= r;i ++){
            if(a[i].id <= mid) add(a[i].y,1);
            else a[i].ans += getsum(a[i].y);
        }
        for(int i = l;i <= r;i ++) if(a[i].id <= mid) add(a[i].y,-1);
    
    }
    
    int main(){
        scanf("%d%d",&n,&mx);
        for(int i = 1;i <= n;i ++){
            scanf("%d%d%d",&a[i].t,&a[i].x,&a[i].y);
            a[i].ans = 0;
        }
        node b; int cnt = 1;
        sort(a+1,a+1+n,cmp);
        for(int i = n;i >= 1;i --){
            if(b.t==a[i].t&&b.x==a[i].x&&b.y==a[i].y){
                a[i].ans += cnt;
                cnt ++;
            }
            else {
                b = a[i];
                cnt = 1;
            }
        }
        for(int i = 1;i <= n;i ++) a[i].id = i;
        cdq(1,n);
        for(int i = 1;i <= n;i ++)
            ans[a[i].ans]++;
        for(int i = 0;i < n;i ++)
            printf("%d
    ",ans[i]);
    }
  • 相关阅读:
    1.3.6 详解build.gradle文件——Android第一行代码(第二版)笔记
    1.3.5 详解项目中的资源——Android第一行代码(第二版)笔记
    1.3.4分析你的第一个Android程序——Android第一行代码(第二版)笔记
    1.3创建你的第一个Android项目——Android第一行代码(第二版)笔记
    1.2搭建开发环境——Android第一行代码(第二版)笔记
    1.1.3 Android应用开发特色——Android第一行代码(第二版)笔记
    函数与方法的区别
    你真的知道敏捷到底是什么吗?
    某个应用的CPU使用率居然达到100%,我该怎么办?
    异常 lock buffer failed for format 0x23
  • 原文地址:https://www.cnblogs.com/kls123/p/10162374.html
Copyright © 2011-2022 走看看