题解 论文题 / [CF850F] Rainbow Balls

传送门
[CF850F] Rainbow Balls

被强迫学习鞅与鞅的停时定理.jpg

读原论文时的笔记直接加在 pdf 上了,pdf 在云盘上
本题和倒数第二道例题十分相似

考虑对一个局面构造一个势函数 \(\phi\)
那么 \(\phi(A_t)+t\) 是一个鞅
可以利用 \(E(\phi(A_t)+t)=E(\phi(A_0)+0)\) 得到 \(E(t)=E(\phi(A_0))-E(\phi(A_t))\)
考虑构造这个势函数 \(\phi(A_i)=\sum f(a_i)\)
那么答案是

\[(\sum f(a_i))-(f(sum)+(n-1)f(0)) \]

那么写出转移式并化简得

\[\sum\frac{a_i(sum-a_i)}{sum(sum-1)}(f(a_{i}-1)+f(a_i+1)-2f(a_i))=-1 \]

一个套路是利用 \(\sum\frac{a_i}{sum}=1\) 来进一步化简要构造的东西
那么只要满足

\[f(a_i-1)+f(a_i+1)-2f(a_i)=\frac{1-sum}{sum-a_i} \]

\(g(i)=f(i+1)-f(i)\),可以得到 \(g(i)\) 的递推式
列出 \(f(sum)\) 的式子来发现是可以化简的
剩下的暴力算出来就好了

点击查看代码
#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define N 100010
#define ll long long
//#define int long long

char buf[1<<21], *p1=buf, *p2=buf;
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf, 1, 1<<21, stdin)), p1==p2?EOF:*p1++)
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;
int a[N], lim;
const ll mod=1e9+7;
ll f[N], g[N], ans, sum;
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;}

signed main()
{
	freopen("ball.in", "r", stdin);
	freopen("ball.out", "w", stdout);

	n=read();
	for (int i=1; i<=n; ++i) lim=max(lim, a[i]=read()), sum+=a[i];
	for (int i=1; i<=lim; ++i) g[i]=(g[i-1]+(1-sum)*qpow(sum-i, mod-2))%mod;
	for (int i=1; i<=lim; ++i) f[i+1]=(f[i]+g[i])%mod;
	for (int i=1; i<=n; ++i) ans=(ans+f[a[i]])%mod;
	ans=(ans-(1-sum)*(sum-1))%mod;
	printf("%lld\n", (ans%mod+mod)%mod);

	return 0;
}
posted @ 2022-07-24 09:26  Administrator-09  阅读(5)  评论(0编辑  收藏  举报