CDQ分治

http://www.lydsy.com/JudgeOnline/problem.php?id=3262

/**************************************************************
Problem: 3262
User: 1349367067
Language: C++
Result: Accepted
Time:3280 ms
Memory:7136 kb
****************************************************************/

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 100011
#define K 200011
using namespace std;
int n,k,tot=0,num=0;
struct flo
{
int a,b,c,ans,s;
flo()
{
ans=s=0;
}
}f[N],nf[N];
pair<int,int> tem[N];
bool cmp(flo a,flo b)
{
if (a.a==b.a&&a.b==b.b) return a.c<b.c;
if (a.a==b.a) return a.b<b.b;
return a.a<b.a;
}
int ans[N]={},U[N]={};
inline int lowbit(int x) {return x&(-x);}
int sum(int x)
{
int res=0;
while (x) {res+=U[x];x-=lowbit(x);}
return res;
}
void update(int x,int a)
{
while (x<=k) {U[x]+=a;x+=lowbit(x);}
}
inline bool check(flo i,flo j)
{
if (i.a==j.a&&i.b==j.b&&i.c==j.c)
return false;
else
return true;
}
bool cmp_(flo i,flo j)
{
if (i.b==j.b) return i.c<j.c;
return i.b<j.b;
}
void solve(int l,int r)
{
if (l==r) return;
int mid=(l+r)/2;
solve(l,mid);solve(mid+1,r);
sort(f+l,f+mid+1,cmp_);
sort(f+mid+1,f+r+1,cmp_);
int l1=l,l2=mid+1;
while (l2<=r)
{
while (l1<=mid&&f[l1].b<=f[l2].b)
{
update(f[l1].c,f[l1].s);
l1++;
}
f[l2].ans+=sum(f[l2].c);
l2++;
}
for (int i=l;i<l1;i++)
update(f[i].c,-f[i].s);
return;
}
int fin[N]={};
void init()
{
scanf("%d%d",&n,&k);
for (int i=1;i<=n;i++)
scanf("%d%d%d",&f[i].a,&f[i].b,&f[i].c);
sort(f+1,f+n+1,cmp);
for (int i=1;i<=n;i++)
{
if (check(f[i],f[i-1]))
{
num++;
nf[num]=f[i];
nf[num].s=1;
}
else
nf[num].s++;
}
for (int i=1;i<=num;i++)
f[i]=nf[i];
solve(1,num);
for (int i=1;i<=num;i++)
fin[f[i].ans+f[i].s-1]+=f[i].s;
for (int i=0;i<n;i++)
printf("%d\n",fin[i]);

}
int main()
{
init();
//system("pause");
return 0;
}

View Code