zoukankan      html  css  js  c++  java
  • 【BZOJ】3262: 陌上花开

    3262: 陌上花开

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

     

    Source

     
    [Submit][Status][Discuss]


    HOME Back

    三维偏序模板题。套路:第一维排序,第二维cdq,第三维树状数组。cdq的具体方法类似于归并排序,将左区间和右区间递归处理。把左右区间按第二维排序,双指针扫描,当右区间i一定时,在左边扫j,当第二维还满足条件时,在值域树状数组上找到j第三维的值,加上相同类型j的个数。当第二维j超过i时,在树状数组上查询小于等于i第三维的j的个数,更新答案。最后一定要把树状数组还原。

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    
    int n, k, num[200005];
    
    struct node {
        int a, b, c, w, ans;
    } qwq[100005], qaq[100005];
    
    bool cmp1 ( node a, node b ) {
        if ( a.a == b.a ) {
            if ( a.b == b.b ) return a.c < b.c;
            return a.b < b.b;
        }
        return a.a < b.a;
    }
    
    bool cmp2 ( node a, node b ) {
        if ( a.b == b.b ) return a.c < b.c;
        return a.b < b.b;
    }
    
    int lowbit ( int x ) {
        return x & -x;
    }
    
    int pre[200005];
    
    void add ( int x, int d ) {
        for ( int i = x; i <= k; i += lowbit ( i ) )
            pre[i] += d;
    }
    
    int query ( int x ) {
        int ans = 0;
        for ( int i = x; i; i -= lowbit ( i ) )
            ans += pre[i];
        return ans;
    }
    
    void CDQ ( int l, int r ) {
        if ( l == r ) return ;
        int mid = ( l + r ) >> 1;
        CDQ ( l, mid ); CDQ ( mid + 1, r );
        int i = mid + 1, j = l;
        sort ( qaq + l, qaq + mid + 1, cmp2 );
        sort ( qaq + mid + 1, qaq + r + 1, cmp2 );
        for ( ; i <= r; i ++ ) {
            while ( qaq[j].b <= qaq[i].b && j <= mid ) {
                add ( qaq[j].c, qaq[j].w ); j ++;
            }
            qaq[i].ans += query ( qaq[i].c );
        }
        for ( i = l; i < j; i ++ ) add ( qaq[i].c, -qaq[i].w );
    }
    
    int main ( ) {
        //freopen ( "testdata.in", "r", stdin );
        //freopen ( "a.out", "w", stdout );
        scanf ( "%d%d", &n, &k );
        for ( int i = 1; i <= n; i ++ )
            scanf ( "%d%d%d", &qwq[i].a, &qwq[i].b, &qwq[i].c );
        sort ( qwq + 1, qwq + 1 + n, cmp1 );
        int cnt = 0, sum = 0;
        for ( int i = 1; i <= n; i ++ ) {
            cnt ++;
            if ( qwq[i].a != qwq[i+1].a || qwq[i].b != qwq[i+1].b || qwq[i].c != qwq[i+1].c ) {
                qaq[++sum] = qwq[i];
                qaq[sum].w = cnt;
                cnt = 0;
            }
        }
        CDQ ( 1, sum );
        for ( int i = 1; i <= sum; i ++ ) num[qaq[i].ans + qaq[i].w - 1] += qaq[i].w;
        for ( int i = 0; i < n; i ++ ) printf ( "%d
    ", num[i] );
        return 0;
    }

     【8.21更新】CDQ里面用sort很慢啊qwq,直接开个辅助数组归并比较优秀。

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    
    int n, k, tot;
    int ans[100005];
    
    struct node {
        int a, b, c, sum, ans;
    } init[100005], flower[100005];
    
    bool cmp ( node a, node b ) {
        if ( a.a == b.a ) {
            if ( a.b == b.b ) return a.c < b.c;
            return a.b < b.b;
        }
        return a.a < b.a;
    }
    
    int lowbit ( int x ) {
        return x & -x;
    }
    
    int pre[200005];
    void add ( int pos, int d ) {
        for ( int i = pos; i <= k; i += lowbit ( i ) )
            pre[i] += d;
    }
    
    int query ( int pos ) {
        int ans = 0;
        for ( int i = pos; i; i -= lowbit ( i ) )
            ans += pre[i];
        return ans;
    }
    
    node fz[100005];
    void CDQ ( int L, int R ) {
        if ( L == R ) return ;
        int mid = ( L + R ) >> 1; int qwq = 0;
        CDQ ( L, mid ); CDQ ( mid + 1, R );
        int i = L, j = mid + 1;
        while ( i <= mid && j <= R ) {
            if ( flower[i].b <= flower[j].b ) {
                add ( flower[i].c, flower[i].sum );
                fz[++qwq] = flower[i++];
            } else {
                flower[j].ans += query ( flower[j].c );
                fz[++qwq] = flower[j++];
            }
        }
        for ( ; j <= R; j ++ ) { flower[j].ans += query ( flower[j].c ); fz[++qwq] = flower[j]; }
        for ( ; i <= mid; i ++ ) { fz[++qwq] = flower[i]; add ( flower[i].c, flower[i].sum ); }
        for ( int i = L; i <= mid; i ++ ) add ( flower[i].c, -flower[i].sum );
        int o = 0;
        for ( i = L; i <= R; i ++ ) flower[i] = fz[++o];
    }
    
    int main ( ) {
        scanf ( "%d%d", &tot, &k );
        for ( int i = 1; i <= tot; i ++ )
            scanf ( "%d%d%d", &init[i].a, &init[i].b, &init[i].c );
        int cnt = 0;
        sort ( init + 1, init + 1 + tot, cmp );
        for ( int i = 1; i <= tot; i ++ ) {
            cnt ++;
            if ( init[i].a != init[i+1].a || init[i].b != init[i+1].b || init[i].c != init[i+1].c ) {
                flower[++n] = init[i];
                flower[n].sum = cnt;
                cnt = 0;
            }
        }    
        CDQ ( 1, n );
        for ( int i = 1; i <= n; i ++ ) ans[flower[i].ans+flower[i].sum-1] += flower[i].sum;
        for ( int i = 0; i < tot; i ++ ) printf ( "%d
    ", ans[i] );
        return 0;
    }
  • 相关阅读:
    超全面的.NET GDI+图形图像编程教程
    VS插件开发
    Vue.js 学习笔记 第7章 组件详解
    Vue.js 学习笔记 第6章 表单与v-model
    Vue.js 学习笔记 第5章 内置指令
    Vue.js 学习笔记 第4章 v-bind 及 class与style绑定
    Vue.js 学习笔记 第3章 计算属性
    Vue.js 学习笔记 第2章 数据绑定和第一个Vue应用
    Vue.js 学习笔记 第1章 初识Vue.js
    Microsoft Visual Studio 2017 for Mac Preview 下载+安装+案例Demo
  • 原文地址:https://www.cnblogs.com/wans-caesar-02111007/p/9489921.html
Copyright © 2011-2022 走看看