Kd Tree TLE7个点求调
查看原帖
Kd Tree TLE7个点求调
419144
luckydrawbox楼主2023/8/21 10:35

RT

#include<bits/stdc++.h>
#define ll long long
using namespace std;
long long read(){
	long long x=0,f=1;char ch=getchar();
	while(!isdigit(ch))
	{if(ch=='-') f=-1;ch=getchar();}
	while(isdigit(ch)){x=x*10+ch-48;ch=getchar();}
	return x*f;
}
void write(long long x){
    if(x<0) putchar('-'),x=-x;
    if(x>9) write(x/10);
    putchar(x%10+'0');
}
const int N=5e4+10;
int n,m;
const int DE=4;//3维 
int nde=0,L[DE],R[DE];
struct Node{
	int fi;
	int w[DE],val;
}s[N];
bool cmp(int p,int q){
	return s[p].w[nde]==s[q].w[nde]?p<q:s[p].w[nde]<s[q].w[nde];
}
#define ls(p) a[p].tl
#define rs(p) a[p].tr
struct KD{
	const double A=0.725;
	int rt,tot,g[N],ans;
	struct Tree{
		int tl,tr,de,sz;
		int l[DE],r[DE],mx;
	}a[N];
	void dfs(int p){
		if(ls(p))dfs(ls(p));
		g[++tot]=p;
		if(rs(p))dfs(rs(p));
	}
	void update(int p,int son,int de){
		a[p].l[de]=min(a[p].l[de],a[son].l[de]);
		a[p].r[de]=max(a[p].r[de],a[son].r[de]);
	}
	void pushup(int p){
		a[p].sz=a[ls(p)].sz+a[rs(p)].sz+1;
		a[p].mx=max(s[p].val,max(a[ls(p)].mx,a[rs(p)].mx));
		for(register int i=1;i<DE;i++)a[p].l[i]=a[p].r[i]=s[p].w[i];
		if(ls(p))for(register int i=1;i<DE;i++)update(p,ls(p),i);
		if(rs(p))for(register int i=1;i<DE;i++)update(p,rs(p),i);
	}
	double fangc(int l,int r,int de){
		double av=0,sa=0;
		for(register int i=l;i<=r;i++)av+=s[g[i]].w[de];
		av/=double(r-l+1);
		for(register int i=l;i<=r;i++)
			sa+=(av-s[g[i]].w[de])*(av-s[g[i]].w[de]);
		return sa;
	}
	int build(int l,int r){
		if(l>r)return 0;
		int p=(l+r)>>1;
		double fcm=1e18,fc;
		nde=0;
		/*for(register int i=1;i<DE;i++){
			fc=fangc(l,r,i);
			if(!nde||fcm>fc)
				nde=i,fcm=fc;
		}*/
		nde=(nde+1)%3+1;
		nth_element(g+l,g+p,g+r+1,cmp);
		a[g[p]].de=nde;
		ls(g[p])=build(l,p-1);rs(g[p])=build(p+1,r);
		pushup(g[p]);return g[p];
	}
	void rebuild(int &p){
		tot=0;dfs(p);p=build(1,tot);
	} 
	bool bad(int p){
		return a[p].sz*A<=(double)max(a[ls(p)].sz,a[rs(p)].sz);
	}
	void insert(int &p,int x){
		if(!p){
			pushup(p=x);return;
		}
		if(s[x].w[a[p].de]==s[p].w[a[p].de]?x<p:s[x].w[a[p].de]<s[p].w[a[p].de])
			insert(ls(p),x);
		else insert(rs(p),x);
		pushup(p);
		if(bad(p))rebuild(p);
	}
	void query(int p,int *l,int *r){
		if(!p)return;
		if(a[p].mx<=ans)return;
		bool flag1=1,flag2=1;
		/*for(register int i=1;i<DE;i++){
			if(r[i]<a[p].l[i]||a[p].r[i]<l[i])return;
			if(r[i]<a[p].r[i]||a[p].l[i]<l[i])flag1=0;
			if(r[i]<s[p].w[i]||s[p].w[i]<l[i])flag2=0;
		}
		if(flag1){
			ans=max(ans,a[p].mx);
			return;
		}
		ans=max(ans,flag2*s[p].val);*/
		if(r[1]<a[p].l[1]||r[2]<a[p].l[2]||r[3]<a[p].l[3])
			return;
		if(r[1]>=a[p].r[1]&&r[2]>=a[p].r[2]&&r[3]>=a[p].r[3]){
			ans=max(ans,a[p].mx);return;
		}
		if(r[1]>=s[p].w[1]&&r[2]>=s[p].w[2]&&r[3]>=s[p].w[3]){
			ans=max(ans,s[p].val);
		}
		if(ans<a[ls(p)].mx)
			query(ls(p),l,r);
		if(ans<a[rs(p)].mx)
			query(rs(p),l,r);
		return;
	}
	void change(int p,int x,int val){
		if(p==x){
			s[p].val=val;
			a[p].mx=max(a[p].mx,s[p].val);return;
		}
		if(s[x].w[a[p].de]==s[p].w[a[p].de]?x<p:s[x].w[a[p].de]<s[p].w[a[p].de])
			change(ls(p),x,val);
		else change(rs(p),x,val);
		a[p].mx=max(a[p].mx,max(a[ls(p)].mx,a[rs(p)].mx));
	}
}kd;
bool cmp2(Node x,Node y){
	return x.fi==y.fi?(x.w[1]==y.w[1]?(x.w[2]==y.w[2]?x.w[3]<y.w[3]:x.w[2]<y.w[2]):x.w[1]<y.w[1]):x.fi<y.fi; 
}
int main(){
	n=read();
	for(register int i=1;i<=n;i++){
		s[i].fi=read();
		for(register int j=1;j<DE;j++)
			s[i].w[j]=read();
	}
	sort(s+1,s+n+1,cmp2);
	for(register int i=1;i<=n;i++)
		kd.g[i]=i;
	kd.rt=kd.build(1,n);
	int ans=0;
	for(register int j=1;j<DE;j++)L[j]=-1e9;
	for(register int i=1;i<=n;i++){
		kd.ans=0;
		for(register int j=1;j<DE;j++)
			R[j]=s[i].w[j];
		kd.query(kd.rt,L,R);
		ans=max(ans,kd.ans+1);
		kd.change(kd.rt,i,kd.ans+1);
	}
	write(ans);
	return 0;
}

有个很神奇的事情,把 query 和 change 去掉一个就不会T,只会WA

2023/8/21 10:35
加载中...