题解 大佬

传送门

考场上连样例都没看懂,分数取模?果断弃掉。
然而弃掉是不可能的,这辈子都不可能的
所以你们知道把\(\frac{7}{4}\)的分子分母同时乘上1e9+7再相除再向上取整和样例输出只差1是什么样的挣扎吗?

所以先恶补一下分数取模:
就是分子乘上分母的逆元再取模
为什么我就没想到呢

stO @letitdown 的思路最终把我弄懂了:
考虑得到某个特定最大天数t的概率
先考虑最大天数恰好为1的概率, 显然为\((\frac{1}{m})^k\)
那最大天数恰好为2呢?
显然最大天数小于等于2的概率为\((\frac{2}{m})^k\)(就是每天抽到的难度都不大于2的概率)
现在我们要把「至少」转化为「恰好」,深受这道题毒害的朋友们应该有灵感了(雾)
每天抽到的难度都不大于2的情况还包括了一个不合法的全为1
所以我们把它减去,就剩下最大天数恰好为1的概率
\(p[i]\)表示最大天数恰好为i的概率
\(p[i] = ((\frac{i}{m})^k-(\frac{i-1}{m})^k)\)
然后每天的劳累度期望 \(E = \sum\limits^m_{i=1}w_i*p_i\)
最后共有\((n-k+1)\)天,将\(E\)乘上天数输出即可

然而一大坑点:\(n>k\)的情况,应该输出0
为什么不能理解为当题不够(k>n)做的时候只做前k道?
难道默认题不够写就完全不写了吗?
传递负能量,一看就不是高考题,就不是高考题那味
LBW如是说
好吧一个比较合理的解释是当\(n>k\)时,可行的做题天数为0,所以难度为0
大概就是这样吧

Code:

#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define N 100010
#define ll long long 
#define ld long double
#define usd unsigned
#define ull unsigned long long
//#define int long long 

#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf, 1, 1<<21, stdin)), p1==p2?EOF:*p1++)
char buf[1<<21], *p1=buf, *p2=buf;
inline int read() {
	int ans=0, f=1; char c=getchar();
	while (!isdigit(c)) {if (c=='-') f=-f; c=getchar();}
	while (isdigit(c)) {ans=(ans<<3)+(ans<<1)+(c^48); c=getchar();}
	return ans*f;
}

int n, m, k;
ll w[N], p[N];
ll fac[N], inv[N];
const ll mod=1e9+7;

ll qpow(ll a, ll b) {
	ll ans=1;
	while (b) {
		if (b&1) ans=ans*a%mod;
		a=a*a%mod; b>>=1;
	}
	return ans;
}

signed main()
{
	#ifdef DEBUG
	freopen("1.in", "r", stdin);
	#endif
	ll ans=0;
	
	n=read(); m=read(); k=read();
	if (k>n) {puts("0"); return 0;}
	for (int i=1; i<=m; ++i) w[i]=read();
	fac[0]=fac[1]=1; inv[0]=inv[1]=1;
	for (int i=2; i<=m; ++i) fac[i]=fac[i-1]*i%mod;
	for (int i=2; i<=m; ++i) inv[i]=(mod-mod/i)*inv[mod%i]%mod;
	ll t = qpow(inv[m], k);
	for (int i=1; i<=m; ++i) 
		p[i]=((1ll*w[i]*((qpow(i, k)-qpow(i-1, k))%mod+mod)%mod*t%mod)+p[i-1])%mod;
	//cout<<p[m]<<endl;
	ans = (n-k+1)*p[m]%mod;
	printf("%lld\n", ans);

	return 0;
}
posted @ 2021-06-10 20:31  Administrator-09  阅读(23)  评论(0编辑  收藏  举报