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