陌上花开
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;
}