题解 P5130 【纯粹的弹幕地狱】
随手水~
首先要求出每一次子弹命中的概率。
设子弹起始位置为
所以考虑枚举
确定了
这个式子肯定可以莫比乌斯反演无疑了;但是这里提供一种其他做法。
后面那个求和到底是什么东西?
注意到一个性质:对于
于是所求式为:
直接
还剩下
上面的和是合法的方案数,除以总共的方案数就是概率,最后乘以
代码:
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#define mod 19260817
using namespace std;
const int MAXN = 10000005;
typedef long long ll;
ll n,k,a,b,c;
int prime[750005],tot = 0;
ll phi[MAXN];
bool vis[MAXN];
inline void make_table(int n)
{
phi[1] = 1;
for(int i = 2; i<=n; i++)
{
if(!vis[i])
{
prime[++tot] = i;
phi[i] = i-1;
}
for(int j = 1; j<=tot&&i*prime[j]<=n; j++)
{
vis[i*prime[j]] = true;
if(i%prime[j]==0)
{
phi[i*prime[j]] = phi[i]*prime[j];
break;
}
else phi[i*prime[j]] = phi[i]*(prime[j]-1);
}
}
}
inline ll qpow(ll a, ll b)
{
ll res = 1;
while(b)
{
if(b&1) res = res*a%mod;
a = a*a%mod;
b >>= 1;
}
return res;
}
inline ll inv(ll x)
{
return qpow(x,mod-2);
}
int main()
{
cin >> n >> a >> b >> c >> k;
make_table(n+5);
ll cnt = 0;
ll inv2 = inv(2);
for(int i = 2; i<=n; i++)
cnt = (cnt+((n+1)*phi[i]%mod-(phi[i]*i%mod*inv2)%mod+mod)%mod*(n-i+1)%mod*8%mod)%mod;
cnt = (cnt+n*n%mod*4%mod+4*n%mod*(n+1)%mod)%mod;
ll totnum = (n+1)*(n+1)%mod*((n+1)*(n+1)%mod)%mod;
ll prob = cnt*inv(totnum)%mod;
ll dmg = (a*(k*(k+1)%mod*(2*k+1)%mod*inv(6)%mod)%mod+
b*(k*(k+1)%mod*inv(2)%mod)%mod+c*k%mod)%mod;
cout << prob*dmg%mod << endl;
return 0;
}
这个方法能否拓展到低于线性的时间尚未可知,我暂时没有好的想法。不过莫比乌斯反演倒是肯定行。