您的位置:首页 > 其它

BZOJ3262: 陌上花开

2016-10-13 14:45 316 查看
传送门

CDQ分治

之前做过一道类似的题,不过这个由二维变三维了。一维sort,二维CDQ,三维树状数组,总体复杂度$O(Nlog^2N)$。这个有点恶心就是$\leq$,如果是$<$的话就要简单很多。

其实对输入数据做一下小修改,把等级相同的合并就行了。

//BZOJ 3262
//by Cydiater
//2016.10.13
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <queue>
#include <map>
#include <ctime>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <iomanip>
using namespace std;
#define ll long long
#define up(i,j,n)		for(int i=j;i<=n;i++)
#define down(i,j,n)		for(int i=j;i>=n;i--)
const int MAXN=1e6+5;
const int oo=0x3f3f3f3f;
inline int read(){
char ch=getchar();int x=0,f=1;
while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int N,LIM,c[MAXN],cnt[MAXN],top=0;
struct flowers{
int x,y,z,id,ans,c;
}a[MAXN],b[MAXN];
namespace solution{
inline bool cmp(flowers x,flowers y){
if(x.y==y.y){
if(x.z==y.z)return x.x<y.x;
return      x.z<y.z;
}
return x.y<y.y;
}
inline bool leq(flowers x,flowers y){
if(x.x==y.x){
if(x.y==y.y)	return x.z<y.z;
return 		x.y<y.y;
}
return x.x<y.x;
}
void init(){
N=read();LIM=read();
up(i,1,N){
int x=read(),y=read(),z=read();
a[i]=(flowers){x,y,z,i,0,1};
}
sort(a+1,a+N+1,leq);
up(i,1,N){
if(i==1||leq(a[i-1],a[i]))a[++top]=a[i];
else                      a[top].c++;
}
int tmp=N;N=top;top=tmp;
up(i,1,N)a[i].x=i;
sort(a+1,a+N+1,cmp);
}
inline int lowbit(int i){return (i&(-i));}
inline void insert(int pos,int v){for(int i=pos;i<=LIM;i+=lowbit(i))c[i]+=v;}
inline int get(int pos){int tmp=0;for(int i=pos;i>=1;i-=lowbit(i))tmp+=c[i];return tmp;}
void slove(int leftt,int rightt){
if(leftt==rightt){
a[leftt].ans+=a[leftt].c-1;
return;
}
int mid=(leftt+rightt)>>1;
slove(leftt,mid);slove(mid+1,rightt);
int point=leftt;
up(i,mid+1,rightt){
while(point<=mid&&a[point].x<=a[i].x)insert(a[point++].z,a[point].c);
a[i].ans+=get(a[i].z);
}
int j=leftt,k=mid+1;
up(i,leftt,point-1)insert(a[i].z,-(a[i].c));
up(i,leftt,rightt)b[i]=((j<=mid&&a[j].x<a[k].x)||k>rightt)?a[j++]:a[k++];
up(i,leftt,rightt)a[i]=b[i];
}
void output(){
memset(cnt,0,sizeof(cnt));
up(i,1,N)cnt[a[i].ans]+=a[i].c;
up(i,0,top-1)printf("%d\n",cnt[i]);
}
}
int main(){
//freopen("input.in","r",stdin);
using namespace solution;
init();
slove(1,N);
output();
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: