zoukankan      html  css  js  c++  java
  • LOJ112三维偏序

    题目描述
    (N)个元素,第$ i (个元素有)a_i 、b_i、c_i$ 三个属性,设 (f(i)) 表示满足 (a_j leq a_i) 且 $b_j leq b_i $且 (c_j leq c_i) 的 j 的数量。

    对于 $ d in [0,n) $,求 (f(i)=d)(i) 的数量。
    输入格式
    第一行两个整数(n 、k),分别表示元素数量和最大属性值。

    之后 (n) 行,每行三个整数(a_i 、b_i、c_i),分别表示三个属性值。
    输出格式
    输出 (n) 行,第 (d+1) 行表示 (f(i)=d)(i) 的数量。
    样例
    输入复制

    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
    1
    3
    0
    1
    0
    1
    0
    0
    1
    

    数据范围与提示
    (nleq100000)
    (kleq200000)

    CDQ分治模板题目

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=1e5+10;
    const int maxm=2e5+10;
    struct node
    {
        int a,b,c,cnt,id;
        bool operator < (const node & x)const 
        {
            if(a!=x.a)return a<x.a;
            if(b!=x.b)return b<x.b;
            if(c!=x.c)return c<x.c;
            return 0;
        }
    }sz[maxn],f[maxn];
    int n,m;
    int ans[maxn];
    int sum[maxm];
    void add(int pos,int v)
    {
        for(int i=pos;i<=m;i+=(i&(-i)))
            sum[i]+=v;
    }
    int query(int pos)
    {
        int ans=0;
        for(int i=pos;i;i-=(i&(-i)))
            ans+=sum[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 q=l,h=mid+1,p=l;
        while(q<=mid&&h<=r)
        {
            if(sz[q].b<=sz[h].b)
            {
                f[p]=sz[q];
                add(sz[q].c,sz[q].cnt);
                ++p,++q;
            }
            else
            {
                f[p]=sz[h];
                int tp=query(sz[h].c);
                ans[sz[h].id]+=tp;
                ++p;++h;
            }
        }
        while(q<=mid)
        {
            f[p]=sz[q];
            add(sz[q].c,sz[q].cnt);
            ++p,++q;
        }
        while(h<=r)
        {
            f[p]=sz[h];
            int tp=query(sz[h].c);
            ans[sz[h].id]+=tp;
            ++p;++h;
        }
        for(int i=1;i<=m;++i)sum[i]=0;
        for(int i=l;i<=r;++i)sz[i]=f[i];
    }
    int rt[maxn];
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;++i)scanf("%d%d%d",&sz[i].a,&sz[i].b,&sz[i].c),sz[i].cnt=1;
        sort(sz+1,sz+1+n);
        int nn=1;sz[1].id=1;
        for(int i=2;i<=n;++i)
        {
            if(sz[nn].a==sz[i].a&&sz[nn].b==sz[i].b&&sz[nn].c==sz[i].c)sz[nn].cnt++;
            else 
            {
                ++nn;sz[nn].a=sz[i].a;sz[nn].b=sz[i].b;sz[nn].c=sz[i].c;sz[nn].cnt=1;sz[nn].id=nn;
            }
        }
        cdq(1,nn);
        for(int i=1;i<=nn;++i)ans[sz[i].id]+=sz[i].cnt;
        for(int i=1;i<=nn;++i)rt[ans[sz[i].id]]+=sz[i].cnt;
        for(int i=1;i<=n;++i)printf("%d
    ",rt[i]);
        return 0;
    }
    
  • 相关阅读:
    两个栈实现队列
    重建二叉树
    最大的K个数
    堆排序
    Android 强制竖屏
    屏蔽输入框的焦点
    Android 全屏显示的方法(不包含状态栏)
    android 布局之scrollview
    clean之后R文件消失
    thinkphp
  • 原文地址:https://www.cnblogs.com/gryzy/p/15476276.html
Copyright © 2011-2022 走看看