李超线段树28分求卡精度+不知道为什么大数据 T 飞了+悬关
查看原帖
李超线段树28分求卡精度+不知道为什么大数据 T 飞了+悬关
1398621
all_for_god楼主2025/7/26 11:13

DP 都是正常去做,样例也很对,然后就错了。

这个是代码

#include<bits/stdc++.h>
using namespace std;
#define ld double
const ld eps=1e-15,inf=1e15+7;
const int N=2e5+7;
ld f[N],tmp[N];int g[N],tr[N<<2],sign[N<<2],n,m,tot=0;
struct node{ld k,b;}seg[N];
ld get(int id,int x){return seg[id].k*tmp[x]+seg[id].b;}
bool eq(ld x,ld y){ld z=x-y;return (z<=eps&&z>=-eps);}
bool cmp(int u,int v,int x){ld a=get(u,x),b=get(v,x);return (a>b)||(eq(a,b)&&g[u]<g[v]);}//尽量使分的段数最小 
#define ls (u<<1)
#define rs (u<<1|1)
#define mid ((l+r)>>1)
void update(int u,int l,int r,int x){
	if(sign[u]!=tot)sign[u]=tot,tr[u]=n+1;
	if(cmp(x,tr[u],tmp[mid]))swap(tr[u],x);
	if(cmp(x,tr[u],tmp[l]))update(ls,l,mid,x);
	if(cmp(x,tr[u],tmp[r]))update(rs,mid+1,r,x);
}
int query(int u,int l,int r,int x){
	if(sign[u]!=tot)sign[u]=tot,tr[u]=n+1;
	if(l==r)return tr[u];
	int res=x<=mid?query(ls,l,mid,x):query(rs,mid+1,r,x);
	return cmp(tr[u],res,x)?tr[u]:res;
}
void calc(ld val){//记得加初始化 
	seg[n+1]={0,-inf};f[n]=0;seg[n]={(-1.0)/n,1.0};update(1,0,n,n);
	for(int i=n-1;i>=0;i--){
		int j=query(1,0,n,i);
		f[i]=get(j,i)+val,g[i]=g[j]+1;
		if(i==0)break;
		seg[i]={(-1.0)/i,1.0+f[i]};update(1,0,n,i);
	}
}
#undef mid
signed main(){
	ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
	cin>>n>>m;for(int i=1;i<=n;i++)tmp[i]=i;
	ld l=-1e10,r=1e10,mid,ans=-1e10;
	while(!eq(l,r)){
		mid=(l+r)/2.0;tot++;calc(mid);
		if(g[0]>=m) ans=mid,r=mid;else l=mid;
	}
	calc(ans);cout<<fixed<<setprecision(9)<<(f[0]-1.0*g[0]*ans);return 0;
}

求救救。

2025/7/26 11:13
加载中...