zoukankan      html  css  js  c++  java
  • 陌上花开 HYSBZ

    陌上花开

    HYSBZ - 3262

    有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

    思路:

    CDQ分治解决三维偏序的模板题。

    推荐去这里学习:https://oi-wiki.org/misc/cdq-divide/

    我写了两个版本,分别是第二维sort和归并排序。

    代码(sort版本):

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <queue>
    #include <stack>
    #include <map>
    #include <set>
    #include <vector>
    #include <iomanip>
    #define ALL(x) (x).begin(), (x).end()
    #define sz(a) int(a.size())
    #define rep(i,x,n) for(int i=x;i<n;i++)
    #define repd(i,x,n) for(int i=x;i<=n;i++)
    #define pii pair<int,int>
    #define pll pair<long long ,long long>
    #define gbtb ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
    #define MS0(X) memset((X), 0, sizeof((X)))
    #define MSC0(X) memset((X), '', sizeof((X)))
    #define pb push_back
    #define mp make_pair
    #define fi first
    #define se second
    #define eps 1e-6
    #define gg(x) getInt(&x)
    #define chu(x) cout<<"["<<#x<<" "<<(x)<<"]"<<endl
    #define du3(a,b,c) scanf("%d %d %d",&(a),&(b),&(c))
    #define du2(a,b) scanf("%d %d",&(a),&(b))
    #define du1(a) scanf("%d",&(a));
    using namespace std;
    typedef long long ll;
    ll gcd(ll a, ll b) {return b ? gcd(b, a % b) : a;}
    ll lcm(ll a, ll b) {return a / gcd(a, b) * b;}
    ll powmod(ll a, ll b, ll MOD) {a %= MOD; if (a == 0ll) {return 0ll;} ll ans = 1; while (b) {if (b & 1) {ans = ans * a % MOD;} a = a * a % MOD; b >>= 1;} return ans;}
    void Pv(const vector<int> &V) {int Len = sz(V); for (int i = 0; i < Len; ++i) {printf("%d", V[i] ); if (i != Len - 1) {printf(" ");} else {printf("
    ");}}}
    void Pvl(const vector<ll> &V) {int Len = sz(V); for (int i = 0; i < Len; ++i) {printf("%lld", V[i] ); if (i != Len - 1) {printf(" ");} else {printf("
    ");}}}
    
    inline void getInt(int *p);
    const int maxn = 1000010;
    const int inf = 0x3f3f3f3f;
    /*** TEMPLATE CODE * * STARTS HERE ***/
    struct node {
        int x, y, z;
        int cnt;
        int ans;
    } a[maxn];
    node b[maxn];
    int Ans[maxn];
    bool cmpx(node aa, node bb)
    {
        if (aa.x != bb.x) {
            return aa.x < bb.x;
        } else if (aa.y != bb.y) {
            return aa.y < bb.y;
        } else {
            return aa.z < bb.z;
        }
    }
    bool cmpy(node aa, node bb)
    {
        if (aa.y != bb.y) {
            return aa.y < bb.y;
        } else {
            return aa.z < bb.z;
        }
    }
    int n, k;
    int tree[maxn];
    int lowbit(int x)
    {
        return -x & x;
    }
    void add(int x, int v)
    {
        while (x < maxn) {
            tree[x] += v;
            x += lowbit(x);
        }
    }
    int ask(int x)
    {
        int res = 0;
        while (x) {
            res += tree[x];
            x -= lowbit(x);
        }
        return res;
    }
    void CDQ(int l, int r)
    {
        if (l == r) {
            return ;
        }
        int mid = (l + r) >> 1;
        CDQ(l, mid);
        CDQ(mid + 1, r);
        // 排序第二维度
        sort(b + l, b + mid + 1, cmpy);
        sort(b + mid + 1, b + r + 1, cmpy);
        int pl = l;
        int pr = mid + 1;
    
        while (pr <= r) {
            while (pl <= mid && b[pl].y <= b[pr].y) {
                add(b[pl].z, b[pl].cnt);// 第三维度加入到树桩数组中
                pl++;
            }
            b[pr].ans += ask(b[pr].z);// 树桩数组求前缀和的形式来求也满足第三维的偏序个数
            pr++;
        }
        repd(i, l, pl - 1) {
            add(b[i].z, -b[i].cnt);//  清空树桩数组。
        }
    }
    int main()
    {
        //freopen("D:\code\text\input.txt","r",stdin);
        //freopen("D:\code\text\output.txt","w",stdout);
        du2(n, k);
        repd(i, 1, n) {
            du3(a[i].x, a[i].y, a[i].z);
        }
        int m = 0;
        int cnt = 0;
        sort(a + 1, a + 1 + n, cmpx);// 排序第一维度
        repd(i, 1, n) {
            cnt++;
            // 把三个维度都相同的缩在一起
            if (a[i].x != a[i + 1].x || a[i].y != a[i + 1].y || a[i].z != a[i + 1].z) {
                b[++m] = a[i];
                b[m].cnt = cnt;
                cnt = 0;
            }
        }
        CDQ(1, m);
        repd(i, 1, m) {
            Ans[b[i].ans + b[i].cnt - 1] += b[i].cnt;
        }
        repd(i, 0, n - 1) {
            printf("%d
    ", Ans[i] );
        }
        return 0;
    }
    
    inline void getInt(int *p)
    {
        char ch;
        do {
            ch = getchar();
        } while (ch == ' ' || ch == '
    ');
        if (ch == '-') {
            *p = -(getchar() - '0');
            while ((ch = getchar()) >= '0' && ch <= '9') {
                *p = *p * 10 - ch + '0';
            }
        } else {
            *p = ch - '0';
            while ((ch = getchar()) >= '0' && ch <= '9') {
                *p = *p * 10 + ch - '0';
            }
        }
    }
    
    
    
    
    
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <queue>
    #include <stack>
    #include <map>
    #include <set>
    #include <vector>
    #include <iomanip>
    #define ALL(x) (x).begin(), (x).end()
    #define sz(a) int(a.size())
    #define rep(i,x,n) for(int i=x;i<n;i++)
    #define repd(i,x,n) for(int i=x;i<=n;i++)
    #define pii pair<int,int>
    #define pll pair<long long ,long long>
    #define gbtb ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
    #define MS0(X) memset((X), 0, sizeof((X)))
    #define MSC0(X) memset((X), '', sizeof((X)))
    #define pb push_back
    #define mp make_pair
    #define fi first
    #define se second
    #define eps 1e-6
    #define gg(x) getInt(&x)
    #define chu(x) cout<<"["<<#x<<" "<<(x)<<"]"<<endl
    #define du3(a,b,c) scanf("%d %d %d",&(a),&(b),&(c))
    #define du2(a,b) scanf("%d %d",&(a),&(b))
    #define du1(a) scanf("%d",&(a));
    using namespace std;
    typedef long long ll;
    ll gcd(ll a, ll b) {return b ? gcd(b, a % b) : a;}
    ll lcm(ll a, ll b) {return a / gcd(a, b) * b;}
    ll powmod(ll a, ll b, ll MOD) {a %= MOD; if (a == 0ll) {return 0ll;} ll ans = 1; while (b) {if (b & 1) {ans = ans * a % MOD;} a = a * a % MOD; b >>= 1;} return ans;}
    void Pv(const vector<int> &V) {int Len = sz(V); for (int i = 0; i < Len; ++i) {printf("%d", V[i] ); if (i != Len - 1) {printf(" ");} else {printf("
    ");}}}
    void Pvl(const vector<ll> &V) {int Len = sz(V); for (int i = 0; i < Len; ++i) {printf("%lld", V[i] ); if (i != Len - 1) {printf(" ");} else {printf("
    ");}}}
    
    inline void getInt(int *p);
    const int maxn = 1000010;
    const int inf = 0x3f3f3f3f;
    /*** TEMPLATE CODE * * STARTS HERE ***/
    struct node {
        int x, y, z;
        int cnt;
        int ans;
    } a[maxn];
    node b[maxn];
    node c[maxn];
    int Ans[maxn];
    bool cmpx(node aa, node bb)
    {
        if (aa.x != bb.x) {
            return aa.x < bb.x;
        } else if (aa.y != bb.y) {
            return aa.y < bb.y;
        } else {
            return aa.z < bb.z;
        }
    }
    bool cmpy(node aa, node bb)
    {
        if (aa.y != bb.y) {
            return aa.y < bb.y;
        } else {
            return aa.z < bb.z;
        }
    }
    int n, k;
    int tree[maxn];
    int lowbit(int x)
    {
        return -x & x;
    }
    void add(int x, int v)
    {
        while (x < maxn) {
            tree[x] += v;
            x += lowbit(x);
        }
    }
    int ask(int x)
    {
        int res = 0;
        while (x) {
            res += tree[x];
            x -= lowbit(x);
        }
        return res;
    }
    void CDQ(int l, int r)
    {
        if (l == r) {
            return ;
        }
        int mid = (l + r) >> 1;
        CDQ(l, mid);
        CDQ(mid + 1, r);
    
        int ql = l;
        int qr = mid + 1;
        repd(i, l, r) {
            if (qr > r || (ql <= mid && b[ql].y <= b[qr].y)) {
                add(b[ql].z, b[ql].cnt);
                c[i] = b[ql++];
            } else {
                b[qr].ans += ask(b[qr].z);
                c[i] = b[qr++];
            }
        }
        ql = l;
        qr = mid + 1;
        repd(i, l, r) {
            if (qr > r || (ql <= mid && b[ql].y <= b[qr].y)) {
                add(b[ql].z, -b[ql].cnt);
                ql++;
            } else {
                qr++;
            }
        }
        repd(i, l, r) {
            b[i] = c[i];
        }
    
    }
    int main()
    {
        //freopen("D:\code\text\input.txt","r",stdin);
        //freopen("D:\code\text\output.txt","w",stdout);
        du2(n, k);
        repd(i, 1, n) {
            du3(a[i].x, a[i].y, a[i].z);
        }
        int m = 0;
        int cnt = 0;
        sort(a + 1, a + 1 + n, cmpx);// 排序第一维度
        repd(i, 1, n) {
            cnt++;
            // 把三个维度都相同的缩在一起
            if (a[i].x != a[i + 1].x || a[i].y != a[i + 1].y || a[i].z != a[i + 1].z) {
                b[++m] = a[i];
                b[m].cnt = cnt;
                cnt = 0;
            }
        }
        CDQ(1, m);
        repd(i, 1, m) {
            Ans[b[i].ans + b[i].cnt - 1] += b[i].cnt;
        }
        repd(i, 0, n - 1) {
            printf("%d
    ", Ans[i] );
        }
        return 0;
    }
    
    inline void getInt(int *p)
    {
        char ch;
        do {
            ch = getchar();
        } while (ch == ' ' || ch == '
    ');
        if (ch == '-') {
            *p = -(getchar() - '0');
            while ((ch = getchar()) >= '0' && ch <= '9') {
                *p = *p * 10 - ch + '0';
            }
        } else {
            *p = ch - '0';
            while ((ch = getchar()) >= '0' && ch <= '9') {
                *p = *p * 10 + ch - '0';
            }
        }
    }
    
    本博客为本人原创,如需转载,请必须声明博客的源地址。 本人博客地址为:www.cnblogs.com/qieqiemin/ 希望所写的文章对您有帮助。
  • 相关阅读:
    开源 Serverless 里程碑:Knative 1.0 来了
    以一致的体验交付和管理云原生多集群应用
    iLogtail使用入门K8S环境日志采集到SLS
    如何在golang代码里面解析容器镜像
    mac vmware 无法复制粘贴
    使用vi编辑时上下左右方向键被转化为A、B、C、D
    left join 和 left outer join 的区别
    设计模式之 适配器模式
    设计模式之 命令模式
    设计模式学习之 策略模式
  • 原文地址:https://www.cnblogs.com/qieqiemin/p/11552647.html
Copyright © 2011-2022 走看看