【bzoj 3262】陌上花开

陌上花开

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

1 <= N <= 100,000, 1 <= K <= 200,000

Source

树套树 CDQ分治
作死写树套树,好吧我输了,以后补一补cdq分治

//unsolve
#include<bits/stdc++.h>
#define __de__
using namespace std;
const int maxn = 200000;
int pool[maxn],cnt;
int lch[maxn],rch[maxn],w[maxn],v[maxn],s[maxn],rnd[maxn];
int cntt[maxn];
int N,M;
struct data
{
    int a,b,c,id;   
};
data in[maxn];
bool cmp(data _a,data _b)
{
    if(_a.a==_b.a)
    {
        if(_a.b==_b.b)
        {
            return _a.c<_b.c;
        }
        else
        {
            return _a.b<_b.b;
        }
    }
    return _a.a<_b.a;

}
struct treap
{
    int root;
    void pushup(int nd)
    {
        s[nd]=s[lch[nd]]+s[rch[nd]]+v[nd];
    }
    void rturn(int &nd)
    {
        int k=lch[nd];
        lch[nd]=rch[k];
        rch[k]=nd;
        s[k]=s[nd];
//      pushup(nd);
        pushup(nd);
        nd=k;   
    }
    void lturn(int &nd)
    {
        int k=rch[nd];
        rch[nd]=lch[k];
        lch[k]=nd;
    //  pushup(nd);
        s[k]=s[nd];
        pushup(nd);
        nd=k;

    }
    void insert(int wc)
    {
        insert(this->root,wc);
    }
    int getrank(int wc)
    {
        return getrank(this->root,wc);  
    }
    void insert(int &nd,int wc)
    {
        if(nd==0)
        {
            nd=++cnt;
            w[nd]=wc;
            s[nd]++;v[nd]++;
            rnd[nd]=rand();
            return ;            
        }
        s[nd]++;
        if(w[nd]==wc)
        {
            v[nd]++;
            return;
        }
        else if(wc<w[nd])
        {
            insert(lch[nd],wc);
            if(rnd[lch[nd]] > rnd[nd])
            {
                rturn(nd);
            }
        }
        else
        {
            insert(rch[nd],wc);
            if(rnd[rch[nd]] > rnd[nd])
            {
                lturn(nd);
            }
        }
    }
    int getrank(int nd,int wc)
    {
        if(nd==0)return -0x7fffffff;
        if(w[nd]==wc)return v[nd]+s[lch[nd]];
        else if(w[nd]>wc)
        {
            return getrank(lch[nd],wc);
        }
        else
            return s[lch[nd]]+v[nd]+getrank(rch[nd],wc);
    }
    void dfs()
    {
        dfs(this->root);
    }
    void dfs(int nd)
    {
        if(nd==0)return;
        dfs(lch[nd]);cout<<rch[nd]<<" "<<lch[nd]<<" "<<s[nd]<<" "<<w[nd]<<" "<<v[nd]<<" "<<nd<<endl;
        dfs(rch[nd]);
    }
};
treap fenwick[maxn];

void modify(int n,int num)
{
    while(n<=M)
    {
        cout<<"&&&&&&&&&&&&&&&\n"<<n<<"\n";
        fenwick[n].dfs();
        fenwick[n].insert(num);
        cout<<"after insert\n";
        fenwick[n].dfs();
        n+=(n&-n);
    }
}
int sum(int n,int num)
{
    int ans=0;
    while(n>0)
    {
        ans+=fenwick[n].getrank(num);
        n-=(n&-n);
    }
}
#ifndef __de__
int main()
{
    fenwick[0].insert(76);
    fenwick[0].insert(76);
    fenwick[0].dfs();
    cout<<fenwick[0].getrank(76);
    return 0;
}
#endif
#ifdef __de__
int main()
{
    scanf("%d%d",&N,&M);
    for(int i=1;i<=N;i++)
    {
        scanf("%d%d%d",&in[i].a,&in[i].b,&in[i].c);
    }
    sort(in+1,in+N+1,cmp);
    for(int i=1;i<=N;i++)
    {
        cout<<in[i].b<<" "<<in[i].c<<endl;
        if(in[i].a==in[i+1].a&&in[i].b==in[i+1].b&&in[i].c==in[i+1].c&&i!=N)
        {
            cntt[i+1]+=cntt[i]+1;
        }
        else
        {
            int rk=sum(in[i].b,in[i].c);
            cout<<rk<<endl;
            cntt[rk]+=cntt[i]+1;
        }
        modify(in[i].b,in[i].c);
    }
    for(int i=1;i<=N;i++)
        //cout<<cntt[i]<<endl;
    return 0;
}
#endif

对着别人写的抄了一遍

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
struct flower{
    int x,y,z;
    int cnt,ans;
}d[1000010];
int tree[3000010],n,k,tot,num[1000010];
int tmp(flower a,flower b)
{
    if(a.x<b.x) return 1;
    if(a.x>b.x) return 0;
    if(a.y<b.y) return 1;
    if(a.y>b.y) return 0;
    if(a.z<b.z) return 1;
    return 0;
}
int cmp(flower a,flower b)
{
    if(a.y<b.y) return 1;
    if(a.y>b.y) return 0;
    if(a.z<b.z) return 1;
    if(a.z>b.z) return 0;
    if(a.x<b.x) return 1;
    return 0;
}
int lowbit(int x)
{
    return x&(-x);
}
void updata(int x,int v)
{
    while(x<=k)
     {
        tree[x]+=v;
        x+=lowbit(x);
     }
    return;
}
inline int ask(int x)
{
    int sum=0;
    while(x)
     {
        sum+=tree[x];
        x-=lowbit(x);
     }
    return sum;
}
void CDQ(int l,int r)
{
    if(l==r) 
     {
        d[l].ans+=d[l].cnt-1;
        return;
     }
    int mid=(l+r)>>1;
    CDQ(l,mid); CDQ(mid+1,r);
    sort(d+l,d+mid+1,cmp);
    sort(d+mid+1,d+r+1,cmp);
    int j=l;
    for(int i=mid+1;i<=r;++i)
     {
        while(j<=mid&&d[j].y<=d[i].y)
           updata(d[j].z,d[j].cnt),++j; 
        d[i].ans+=ask(d[i].z);
     }
    for(int i=l;i<j;++i) updata(d[i].z,-d[i].cnt);
}
int main()
{
    int i,j;
    scanf("%d%d",&n,&k);
    for(i=1;i<=n;++i) scanf("%d%d%d",&d[i].x,&d[i].y,&d[i].z),d[i].ans=1;
    sort(d+1,d+n+1,tmp);
    for(i=1;i<=n;++i)
     if(i!=1&&d[i].x==d[i-1].x&&d[i].y==d[i-1].y&&d[i].z==d[i-1].z) d[tot].cnt++;
      else d[++tot]=d[i],d[tot].cnt=1;
    CDQ(1,tot);
    sort(d+1,d+tot+1,tmp);
    for(i=1;i<=tot;++i) num[d[i].ans]+=d[i].cnt;
    for(i=1;i<=n;++i) printf("%d\n",num[i]);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值