成熟是一种明亮而不刺眼的光辉,一种圆润而不腻耳的音响,一种不再需要对别人察言观色的从容,一种终于停止向周围申述求告的大气,一种不理会哄闹的微笑,一种洗刷了偏激的淡漠,一种无须声张的厚实,一种并不陡峭的高度。勃郁的豪情发过了酵,尖利的山风收住了劲,湍急的溪流汇成了湖。
——余秋雨《文化苦旅》
期望在有些时候比较难以用逻辑直接推导,我们用更语言化的形式表述,但依然保持严谨。
我们可以使用代数变形,使用前缀和,或者数据结构维护转移。
https://www.luogu.com.cn/problem/P4550
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=200010,M=3*N;
double f[N],g[N];
int n;
signed main()
{
cin>>n;
f[n]=0;
g[n]=0;
for(int i=n-1;i>=0;i--)
{
double p1=1.0*i/n;
double p2=1.0*(n-i)/n;
f[i]=(p2*f[i+1]+1)/(1-p1);
g[i]=(g[i+1]*p2+f[i]*p1+f[i+1]*p2+1)/(1-p1);
}
printf("%.2lf",g[0]);
}
除此以外,我们可以直接模拟。
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=10000000;
double sum;
int n=3;
signed main()
{
for(int t=1;t<=N;t++)
{
set<int>w;
int step=0;
int money=0;
while(1)
{
++step;
//cout<<step<<"\n";
money+=step;
w.insert(rand()%n+1);
if(w.size()==n)
break;
}
sum+=money;
}
cout<<sum/N;
}
但是精度是很难满足相关的要求,并且时间也是极大的。
https://www.luogu.com.cn/problem/P6834
而我们可以通过双指针维护区间属性,用树状数组快速求和。
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=1000010;
const int mod=998244353;
int n,k;
int a[N],b[N];
int lowbit(int x)
{
return x&-x;
}
struct BIT
{
int c[N];
void add(int pos,int k)
{
for(int i=pos;i<N;i+=lowbit(i))
{
c[i]=((c[i]+k)%mod+mod)%mod;
}
}
int query(int x)
{
int res=0;
while(x)
{
res=res+c[x];
res%=mod;
x-=lowbit(x);
}
return res;
}
}T0,T1;
int pow_m(int a,int x)
{
int res=1;
while(x)
{
if(x&1)
{
res=res*a%mod;
}
a=a*a;
a%=mod;
x>>=1;
}
return res;
}
signed main()
{
int ans=0;
cin>>n>>k;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
for(int i=1;i<=n;i++)
b[i]=a[i];
sort(b+1,b+n+1);
int M;
M=unique(b+1,b+n+1)-b-1;
for(int i=1;i<=n;i++)
{
a[i]=lower_bound(b+1,b+M+1,a[i])-b;
}
for(int i=1;i<=n;i++)
{
T0.add(a[i],1);
T1.add(a[i],b[a[i]]);
int st;
if(i-k-1>=1)
{
T0.add(a[i-k-1],-1);
T1.add(a[i-k-1],-b[a[i-k-1]]);
}
st=max(1ll,i-k);
int p=i-st;
int s1=T1.query(a[i]);
int s0=T0.query(a[i]);
int sum=((s0*b[a[i]]%mod-s1)%mod+mod)%mod;
sum=sum*pow_m(p,mod-2)%mod;
ans=(ans+sum)%mod;
}
ans=(ans+b[a[1]])%mod;
printf("%lld\n",ans);
}