[罪人的终幕] 题解
___Furina___ · · 题解
感谢 @PengAo 对这篇题解的建议和修改。
题目大意
定义
题解
下文以求方便,用
注意到
关于变形的证明(以下的
同理,
证毕。
代码如下:
#include<bits/stdc++.h>
#define N 200010
#define I_love_Furina return
#define forever 0
#define foreverr 1
#define Endl endl
#define endl '\n'
#define FIO(s) do{freopen(s".in","r",stdin);freopen(s".out","w",stdout);}while(false)
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
#define db long double
#define chc cout<<114514<<endl
#define int long long
#define lt (p<<1)
#define rt (p<<1|1)
#define mid (l+r>>1)
#define eps 1e-15
#define ma 1e9
#define day 182376
using namespace std;
int n,T,pr[N],num,w[N],t[N<<2];
db k,dp[N],d[N];
bool b[N];
struct line{db k,b;}li[N];
inline int cmp(db x,db y){
if(fabs(x-y)<eps)I_love_Furina forever;
I_love_Furina (x>y?1:-1);
}
inline void mk(int p){li[++num].k=1.0/dp[p],li[num].b=d[w[p]]/dp[p];}
inline db calc(int p,int x){I_love_Furina li[p].k*x+li[p].b;}
inline void upd(int p,int l,int r,int u){
int &v=t[p],tp=cmp(calc(u,mid),calc(v,mid));
if(tp<0)swap(u,v);
int tpl=cmp(calc(u,l),calc(v,l)),tpr=cmp(calc(u,r),calc(v,r));
if(tpl<0)upd(lt,l,mid,u);
if(tpr<0)upd(rt,mid+1,r,u);
}
inline db query(int p,int l,int r,int x){
if(l>x||r<x)I_love_Furina ma;
db ans=calc(t[p],x);
if(l==r)I_love_Furina ans;
I_love_Furina min(ans,min(query(lt,l,mid,x),query(rt,mid+1,r,x)));
}
signed main(){
IOS;//FIO("");
n=2e5;
d[1]=0;
for(int i=2;i<=n;i++){
if(!b[i])pr[++num]=i,d[i]=i;
for(int j=1;j<=num&&i*pr[j]<=n;j++){
b[i*pr[j]]=1;
if(i%pr[j]==0){d[i*pr[j]]=d[i];break;}
d[i*pr[j]]=d[i]+d[pr[j]];
}
}
num=0;
li[0].k=1145,li[0].b=100000000;
cin>>n>>dp[1]>>k;
for(int i=1;i<=n;i++)cin>>w[i];
mk(1);
//cout<<num<<" "<<li[1].k<<" "<<li[1].b<<endl;
upd(1,1,day,1);
for(int i=2;i<=n;i++)dp[i]=1/query(1,1,day,d[w[i]])+k,mk(i),upd(1,1,day,i);
db sum=0;
for(int i=1;i<=n;i++)sum+=dp[i];
printf("%.6Lf",sum);
I_love_Furina forever;
}
P.S. 本来出这道题不容易,还要求我给证明 qnq。