谁来帮忙列文虎克一下这个二分查找
查看原帖
谁来帮忙列文虎克一下这个二分查找
1161172
HaneDaniko楼主2024/6/11 11:41

跑样例第二个就有问题

具体问题在二分查找部分,一份套成函数写,错了,另一份直接拿出来就过了

出问题的地方标出来了

正确的代码

#include<bits/stdc++.h>
using namespace std;
long double f[100001];
int g[100001],nxt[100001],w[100001];
int q[100001];int n,ll,p;
string a[100001];
struct node{
	int l,r;
}no[100001];
void clear(){
	memset(f,0,sizeof f);
	memset(g,0,sizeof g);
	memset(nxt,0,sizeof nxt);
	memset(w,0,sizeof w);
	memset(q,0,sizeof q);
	memset(no,0,sizeof no);
}
long double Power(int w,int x){
    long double ans=1;
    for(int i=1;i<=x;++i){
        ans*=w;
    }
    return ans;
}
long double act(int x,int y){
	return f[x]+Power(abs(w[y]-w[x]-1-ll),p);
}
int main(){
	int cases;
	cin>>cases;while(cases--){
		clear();
		cin>>n>>ll>>p;
		for(int i=1;i<=n;++i){
			cin>>a[i];
			w[i]=w[i-1]+a[i].length()+1;
		}
		int l=0,r=1;q[l]=0;
		no[0]={1,n};
		for(int i=1;i<=n;++i){
			while(l<r-1&&i>no[q[l]].r) l++;
			f[i]=f[q[l]]+Power(abs(w[i]-w[q[l]]-1-ll),p);
			no[q[l]].l++;g[i]=q[l]; 
			while(l<r-1&&act(q[r-1],no[q[r-1]].l)>act(i,no[q[r-1]].l)){
				r--;
				no[q[r]]={0,0};
				q[r]=0;
			}
			/*---------------------------------*/
			int ll=no[q[r-1]].l,rr=no[q[r-1]].r;
            while(ll<=rr){
                int mid=(ll+rr)/2;
                if(act(i,mid)<=act(q[r-1],mid)) rr=mid-1;
                else ll=mid+1;
            }
            /*--------------------------------*/
			if(ll<=n){
				no[q[r-1]].r=ll-1;
				q[r++]=i;
				no[i]={ll,n};
			}
		}
		if(f[n]>1e18){
			cout<<"Too hard to arrange"<<endl;
		}
		else{
			printf("%lld\n",(long long)f[n]);
			int tmp=n;
			while(tmp){
				nxt[g[tmp]]=tmp;
				tmp=g[tmp];
			}
			while(tmp!=n){
				for(int i=tmp+1;i<=nxt[tmp];++i){
					cout<<a[i];
					if(i!=nxt[tmp]) cout<<" ";
				}
				cout<<endl;
				tmp=nxt[tmp];
			}
		}
		cout<<"--------------------"<<endl;
	}
}

错误的代码

#include<bits/stdc++.h>
using namespace std;
long double f[100001];
int g[100001],nxt[100001],w[100001];
int q[100001];int n,ll,p;
string a[100001];
struct node{
	int l,r;
}no[100001];
void clear(){
	memset(f,0,sizeof f);
	memset(g,0,sizeof g);
	memset(nxt,0,sizeof nxt);
	memset(w,0,sizeof w);
	memset(q,0,sizeof q);
	memset(no,0,sizeof no);
}
long double Power(int w,int x){
    long double ans=1;
    for(int i=1;i<=x;++i){
        ans*=w;
    }
    return ans;
}
long double act(int x,int y){
	return f[x]+Power(abs(w[y]-w[x]-1-ll),p);
}
long long search(int i,int l,int r){
	int ll=l,rr=r,ans=rr+1;
	while(ll<=rr){
		int mid=(ll+rr)/2;
		if(act(i,mid)<=act(q[rr-1],mid)){
			rr=mid-1;
			ans=mid;
		}
		else{
			ll=mid+1;
		}
	}
	return ll;
}
int main(){
	int cases;
	cin>>cases;while(cases--){
		clear();
		cin>>n>>ll>>p;
		for(int i=1;i<=n;++i){
			cin>>a[i];
			w[i]=w[i-1]+a[i].length()+1;
		}
		int l=0,r=1;q[l]=0;
		no[0]={1,n};
		for(int i=1;i<=n;++i){
			while(l<r-1&&i>no[q[l]].r) l++;
			f[i]=f[q[l]]+Power(abs(w[i]-w[q[l]]-1-ll),p);
			no[q[l]].l++;g[i]=q[l]; 
			while(l<r-1&&act(q[r-1],no[q[r-1]].l)>act(i,no[q[r-1]].l)){
				r--;
				no[q[r]]={0,0};
				q[r]=0;
			}
			/*--------------------------*/
			int fi=search(i,no[q[r-1]].l,no[q[r-1]].r);
			/*--------------------------*/
			if(fi<=n){
				no[q[r-1]].r=fi-1;
				q[r++]=i;
				no[i]={fi,n};
			}
		}
		if(f[n]>1e18){
			cout<<"Too hard to arrange"<<endl;
		}
		else{
			printf("%lld\n",(long long)f[n]);
			int tmp=n;
			while(tmp){
				nxt[g[tmp]]=tmp;
				tmp=g[tmp];
			}
			while(tmp!=n){
				for(int i=tmp+1;i<=nxt[tmp];++i){
					cout<<a[i];
					if(i!=nxt[tmp]) cout<<" ";
				}
				cout<<endl;
				tmp=nxt[tmp];
			}
		}
		cout<<"--------------------"<<endl;
	}
}
2024/6/11 11:41
加载中...