UOJ题求调
  • 板块学术版
  • 楼主int233
  • 当前回复1
  • 已保存回复1
  • 发布时间2025/6/28 15:46
  • 上次更新2025/6/29 11:09:23
查看原帖
UOJ题求调
333855
int233楼主2025/6/28 15:46

思路是优化 O(n2logn)O(n^2\log n) 的算法,对整个序列进行分块,然后对块内有无元素分讨处理,目前二分部分出现了问题,求调。

#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
typedef long long ll;
const int inf=1000000001,V=2*inf,blo=200;
int n,fp[1000005],rr,rs,z[1000005],ans[1000005],rp[12005],l[12005],R[1000005],qn,cp[1000005],bel[10000005],d[10000005],rk[12005],bels[12005],q;
short fr[71994005];
int las[71994005];
vector<int> vc[1000005];
vector<pair<int,int> > vcs[1000005];
struct node{
	ll x,y;
}c[12005];
int cmp(node aa,node bb){
	if(aa.y==bb.y){
		return aa.x>bb.x;
	}
	return aa.y<bb.y;
}
int getblo(int x){
	return (x-1)/blo+1;
}
int getxx(int x){
	int cur=lower_bound(cp+1,cp+qn+1,x)-cp;
	return cur;
}
int cmp2(int aa,int bb){
	if(z[aa]==z[bb]){
		return aa<bb;
	}
	return z[aa]<z[bb]; 
}
int main(){
	//freopen("jisuanjihe.in","r",stdin);
//	freopen("jisuanjihe.out","w",stdout);
	cin>>n>>q;
	for(int i=1;i<=n;i++){
		cin>>c[i].x>>c[i].y;
		c[i].x=c[i].x*c[i].x+c[i].y*c[i].y;
		c[i].y*=2; 
	}
	sort(c+1,c+n+1,cmp);
	for(int i=1;i<=q;i++){
		cin>>z[i]>>R[i];
		z[i]+=inf;
		cp[i]=z[i];
	}
	sort(cp+1,cp+q+1);
	qn=unique(cp+1,cp+q+1)-cp-1;
	for(int i=1;i<=qn;i++){
		if((i>=2&&getblo(cp[i])!=getblo(cp[i-1]))||(i==1)){
			bel[getblo(cp[i])]=++rs;
		}
		else{
			bel[getblo(cp[i])]=bel[getblo(cp[i-1])];
		}
		vcs[rs].push_back({cp[i],i});
	} 
	for(int i=1;i<=q;i++){
		int t=getblo(z[i]);
		if(!d[t]){
			d[t]=getxx(z[i]);
		}
		else{
			d[t]=min(d[t],getxx(z[i]));
		}
	}
	for(int i=10000001;i>=1;i--){
		if(d[i+1]){
			if(!d[i]){
				d[i]=d[i+1];
			}
			else{
				d[i]=min(d[i],d[i+1]);
			}
		}
	}
	for(int i=1;i<=n;i++){
		rk[i]=1;
		c[i].x+=inf*c[i].y;
		//cout<<c[i].x<<" "<<c[i].y<<endl;
	}
	for(int i=1;i<=n;i++){
		l[i]=rr;
		for(int j=1;j<i;j++){
			++rr;
			fr[rr]=i;
			if(c[j].y==c[i].y){
				//cout<<i<<" "<<j<<endl; 
				rk[j]++;
				continue;
			}
			ll D=(c[i].x-c[j].x)/(c[i].y-c[j].y);
			D++;	
		//	cout<<D-inf<<" "<<j<<" "<<i<<" "<<(c[i].y-c[j].y)<<endl;
			if(D<=cp[1]){
				rk[j]++;
			}
			else{
				rk[i]++;
			}
			if(D<=cp[1]||D>cp[qn]){
				continue;
			}
		//	cout<<D<<endl;
			ll dt;
			
			if(!bel[getblo(D)]){
				dt=d[getblo(D)];
			}
			else{
				int t=getblo(D); 
				vector<pair<int,int> >::iterator cur=lower_bound(vcs[bel[t]].begin(),vcs[bel[t]].end(),make_pair((int)D,0));
				if(cur==vcs[bel[t]].end()){
					dt=d[t+1];
				}
				else{
					dt=(*cur).second;
				}
			}
			las[rr]=fp[dt];
			fp[dt]=rr;
		}
	}
//	cout<<"狗";
	for(int i=1;i<=n;i++){
		bels[rk[i]]=i;
	}
	l[n+1]=rr;
	for(int i=1;i<=q;i++){
		rp[i]=i;
	}
	sort(rp+1,rp+q+1,cmp2);
//	cout<<"狗";
	for(int i=1;i<=q;i++){
		if(getxx(z[rp[i]])>=2&&z[rp[i]]!=z[rp[i-1]]){
			int now=fp[getxx(z[rp[i]])];
			while(now){
				int hs=fr[now],ls;
				ls=now-l[now];//(hs,ls)
				rk[hs]--;
				rk[ls]++;
				now=las[now];
			}
			now=fp[getxx(z[rp[i]])];
			while(now){
				int hs=fr[now],ls;
				ls=now-l[now];//(hs,ls)
				bels[rk[hs]]=hs;
				bels[rk[ls]]=ls;
				now=las[now];
			}
		}
		int ls,rs,mid;
		ls=1,rs=n;
		while(ls<rs){
			mid=(ls+rs+1)>>1;
			if((c[bels[mid]].x-c[bels[mid]].y*z[rp[i]])<=(R[rp[i]]*R[rp[i]]-(z[rp[i]]-inf)*(z[rp[i]]-inf))){
				ls=mid;
			}
			else{
				rs=mid-1;
			}
		}
		if((c[bels[ls]].x-c[bels[ls]].y*z[rp[i]])>(R[rp[i]]*R[rp[i]]-(z[rp[i]]-inf)*(z[rp[i]]-inf))){
			ls=0;
		}
		ans[rp[i]]=ls;
	}
	for(int i=1;i<=q;i++){
		cout<<ans[i]<<endl;
	}
	return 0;
} 
2025/6/28 15:46
加载中...