题意
对每个三维点(x,y,z),只有在这个单位时间存在一个点位于(x’,y’,z’) { x’<x && y’<y && z’<z}时,这个点才能在这个单位时间存活,求每个点的存活时间
思路
对z轴进行离散化,然后对整体进行cdq分治,求每个点之后有几个点
代码实现
#pragma GCC optimize(3,"Ofast","inline")
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int N=1e5+5;
const int M=505;
const int INF=0x3f3f3f3f;
const ll LINF=5e18;
const ull sed=31;
const ll mod=19260817;
const double eps=1e-5;
const double PI=acos(-1.0);
typedef pair<int,int>P;
typedef pair<double,double>Pd;
template<class T>void read(T &x)
{
x=0;int f=0;char ch=getchar();
while(ch<'0'||ch>'9') {f|=(ch=='-');ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
x=f?-x:x;
return;
}
template <typename T> inline void write(T x)
{
if(x<0) putchar('-'), x = -x;
if(x >= 10) write(x/10);
putchar(x%10+'0');
}
int n;
struct loc
{
ull x,y,z;
int pos;
bool flag;
}lcu[N],tmp[N];
int T[N];
ull z[N];
bool cmp(loc a,loc b)
{
if(a.x!=b.x) return a.x<b.x;
if(a.y!=b.y) return a.y<b.y;
return a.z<b.z;
}
bool cmp1(loc a,loc b)
{
return a.y<b.y;
}
ull k1,k2;
ull CoronavirusBeats()
{
ull k3 = k1, k4 = k2;
k1 = k4;
k3 ^= k3 << 23;
k2 = k3 ^ k4 ^ (k3 >> 17) ^ (k4 >> 26);
return k2 + k4;
}
int ans[N];
inline int lowbit(int x) {return x&(-x);}
void add(int x,int val)
{
for(;x<N;x+=lowbit(x)) T[x]=max(T[x],val);
}
void init(int x)
{
for(;x<N;x+=lowbit(x)) T[x]=0;
}
int sum(int x)
{
int ret=0;
for(;x;x-=lowbit(x)) ret=max(ret,T[x]);
return ret;
}
void cdq(int l,int r)
{
if(l==r) return ;
int mid=(l+r)>>1;
cdq(l,mid);
int cnt=0;
for(int i=l;i<=r;i++)
{
tmp[++cnt]=lcu[i];
tmp[cnt].flag=(i>mid);
}
sort(tmp+1,tmp+1+cnt,cmp1);
for(int i=1;i<=cnt;i++)
{
if(tmp[i].flag) ans[tmp[i].pos]=max(ans[tmp[i].pos],sum(tmp[i].z)+1);
else add(tmp[i].z,ans[tmp[i].pos]);
}
for(int i=1;i<=cnt;i++) if(!tmp[i].flag) init(tmp[i].z);
cdq(mid+1,r);
}
int main()
{
//freopen("a.txt","r",stdin);
read(n);read(k1);read(k2);
for(int i=1;i<=n;i++)
{
lcu[i].x=CoronavirusBeats();
lcu[i].y=CoronavirusBeats();
lcu[i].z=z[i]=CoronavirusBeats();
lcu[i].pos=i;
ans[i]=1;
}
sort(z+1,z+1+n);
int m=unique(z+1,z+1+n)-z-1;
for(int i=1;i<=n;i++) lcu[i].z=lower_bound(z+1,z+1+m,lcu[i].z)-z;
sort(lcu+1,lcu+1+n,cmp);
cdq(1,n);
int ret=0;
for(int i=1;i<=n;i++) ret=max(ans[i],ret);
printf("%d\n",ret);
for(int i=1;i<=n;i++)
{
if(i!=1) putchar(' ');
printf("%d",ans[i]-1);
}
puts("");
return 0;
}