题解 集合均值

传送门

先注意一个事情:A集合里初始有个数0
然后令 \(suf[i]=\frac{1}{i+1}+\frac{1}{i+2}+...+\frac{1}{n+1}\)
这个suf是一个数在第 \(i\) 个位置的贡献
于是发现每个数在每个位置是等概率的,于是乘上即可

Code:
#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define N 20000010
#define ll long long
//#define int long long

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;
int a[100010], suf[N], inv[N];
const int mod=998244353;
inline void md(ll& a, ll b) {a+=b; a=a>=mod?a-mod:a;}
inline void md(int& a, int b) {a+=b; a=a>=mod?a-mod:a;}
inline ll qpow(ll a, ll b) {ll ans=1; for (; b; a=a*a%mod,b>>=1) if (b&1) ans=ans*a%mod; return ans;}

namespace force{
	int tot;
	void solve() {
		tot=n;
		for (int i=1; i<m; ++i) for (int i=1; i<=n; ++i) a[++tot]=a[i];
		n=tot;
		ll tem=0, ans=0;
		for (int i=n+1; i; --i) suf[i]=(suf[i+1]+inv[i])%mod;
		for (int i=2; i<=n+1; ++i) tem=(tem+suf[i])%mod;
		tem=tem*inv[n]%mod;
		for (int i=1; i<=n; ++i) ans=(ans+tem*a[i])%mod;
		printf("%lld\n", ans);
		exit(0);
	}
}

namespace task1{
	void solve() {
		ll tem=0, ans=0; int lim=n*m+1;
		for (int i=1; i<=lim; ++i) suf[i]=inv[i];
		for (int i=lim; i; --i) md(suf[i], suf[i+1]);
		for (int i=2; i<=lim; ++i) md(tem, suf[i]);
		tem=tem*inv[n]%mod;
		for (int i=1; i<=n; ++i) ans=(ans+tem*a[i])%mod;
		printf("%lld\n", ans);
		exit(0);
	}
}

namespace force2{
	ll ans, sum;
	bool vis[N];
	void dfs(int u, ll pre) {
		if (u>n) return ;
		pre=pre*inv[n-u+1]%mod;
		for (int i=1; i<=n; ++i) if (!vis[i]) {
			vis[i]=1;
			sum+=a[i];
			ans=(ans+sum*inv[u+1]%mod*pre%mod)%mod;
			dfs(u+1, pre);
			sum-=a[i];
			vis[i]=0;
		}
	}
	void solve() {
		dfs(1, 1);
		printf("%lld\n", ans);
		exit(0);
	}
}

signed main()
{
	freopen("mos.in", "r", stdin);
	freopen("mos.out", "w", stdout);
	
	// cout<<double(sizeof(inv)*2)/1024/1024<<endl;
	n=read(); m=read();
	for (int i=1; i<=n; ++i) a[i]=read();
	inv[0]=inv[1]=1;
	for (int i=2; i<N; ++i) inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod;
	task1::solve();
	// force2::solve();

	return 0;
}
posted @ 2021-11-01 14:26  Administrator-09  阅读(0)  评论(0编辑  收藏  举报