zoukankan      html  css  js  c++  java
  • Bzoj 3262: 陌上花开(CDQ分治)

    3262: 陌上花开
    Time Limit: 20 Sec Memory Limit: 256 MB
    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
    Source
    树套树 CDQ分治

    /*
    三维偏序.
    一维排序,二维CDQ分治,三维树状数组维护.
    求三维LIS.
    先对x排序,再对c分治处理贡献. 
    然后树状数组维护比m小的数的个数.
    貌似还可以树状数组套平衡树搞orz.
    */
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #define MAXN 200001
    using namespace std;
    int n,k,s[MAXN],tot,ans[MAXN],ansrank[MAXN];
    struct data
    {
        int s,c,m,o,be,sum;
        bool operator ==(const data &x)
        {
            return x.s==s&&x.c==c&&x.m==m; 
        }
    }q[MAXN],tmp[MAXN];
    int read()
    {
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();
        return x*f;
    }
    void add(int x,int z)
    {
        while(x<=k) s[x]+=z,x+=x&-x;
        return ;
    }
    int getsum(int x)
    {
        int sum=0;
        while(x>0) sum+=s[x],x-=x&-x;
        return sum;
    }
    bool cmp(const data &x,const data &y)
    {
        if(x.s==y.s&&x.c==y.c) return x.m<y.m;
        if(x.s==y.s) return x.c<y.c;
        return x.s<y.s;
    }
    bool cmp2(const data &x,const data &y)
    {
        if(x.c==y.c) return x.o<y.o;
        return x.c<y.c;
    }
    void slove(int l,int r)
    {
        if(l==r) return ;
        int mid=(l+r)>>1,ll=l,rr=mid+1,cut=0;;
        for(int i=l;i<=mid;i++) q[i].o=1,tmp[ll++]=q[i];
        for(int i=mid+1;i<=r;i++) q[i].o=2,tmp[rr++]=q[i];
        //for(int i=l;i<=r;i++) q[i]=tmp[i];
        sort(tmp+l,tmp+r+1,cmp2);
        for(int i=l;i<=r;i++)
        {
            if(tmp[i].o==1) add(tmp[i].m,tmp[i].sum);
            else ans[tmp[i].be]+=getsum(tmp[i].m);
        }
        for(int i=l;i<=r;i++) if(tmp[i].o==1) add(tmp[i].m,-tmp[i].sum);
        slove(l,mid),slove(mid+1,r);
        return ;
    }
    int main()
    {
        int t=0;
        n=read(),k=read();
        for(int i=1;i<=n;i++)
          tmp[i].s=read(),tmp[i].c=read(),tmp[i].m=read(),tmp[i].sum=1;
        sort(tmp+1,tmp+n+1,cmp);
        for(int i=1;i<=n;i++)
        {
            if(tmp[i]==tmp[i-1]) q[tot].sum++;
            else q[++tot]=tmp[i],q[tot].be=++t;
        }
        sort(q+1,q+tot+1,cmp);
        slove(1,tot);
        for(int i=1;i<=tot;i++) ansrank[ans[q[i].be]+q[i].sum-1]+=q[i].sum;
        for(int i=0;i<n;i++) printf("%d
    ",ansrank[i]);
        return 0;
    }
  • 相关阅读:
    IronRuby:元编程特性【method_missing】的使用
    DNN(DotNetNuke) 3.0感官刺激零距x接触!!! :)
    (MS SQL)如何实现相关文章功能(多关键字匹配)改进版
    谁有微软认证,如MCSD,MCDBA,MCXX等等,马上告诉我
    开源代码2004/12/25 codeproject
    开源代码2004/1220-PDF格式/文件相关
    强烈推荐一个超酷的跨平台、支持多数据库的数据库管理工具
    (MS SQL)如何实现相关文章功能(多关键字匹配)
    DotNetNuke(DNN)从入门到进阶(1)-怎样写自己的模块
    推荐开源代码2004/12/17
  • 原文地址:https://www.cnblogs.com/nancheng58/p/10068070.html
Copyright © 2011-2022 走看看