[势能函数] CF1025G Company Acquisitions
作者:互联网
好神仙的科技。/xia
对于一类特殊的期望问题,构造一个函数来评估某一个局面,满足任意局面在一次操作后的期望函数值都恰好增加 \(1\),那么答案就是最终局面的函数值减去初始局面的函数值,这种函数即势能函数。
记 \(a_i\) 为跟在第 \(i\) 点后面的点的个数,设 \(F(\{a_i\}) = \sum\limits_{i=1}^n f(a_i)\) ,考虑随机出 \(a_i = x, a_j = y\):
\[\Delta = \dfrac 1 2 (f(x+1)+yf(0)+f(y+1)+xf(0)) - (f(x)+f(y)) = 1 \]令 \(f(0) = 0\),则
\[\dfrac 1 2 (f(x+1)+f(y+1))-(f(x)+f(y))=1 \]移项:
\[(\dfrac 1 2 f(x+1)-f(x)) + (\dfrac 1 2 f(y+1)-f(y))=1 \]由于该柿子应对于任何的 \(x,y\) 都成立,则对于任意的 \(x\) 都有 \(\dfrac 1 2 f(x+1) - f(x) = \dfrac 1 2\),
则
\[f(x+1) = 2f(x)+1 \]由 \(f(0)\) 得 \(f(x) = 2^x - 1\)
最终局面的 \(F(\{a_i\} = f(n-1)\),减去开始局面的 \(F(\{a_i\})\) 即为答案。
\(\texttt{Code:}\)
#include <bits/stdc++.h>
using namespace std;
namespace _MoFa {
const int cmd = 1e9 + 7;
int _add(int a, int b) {a += b; return a < cmd ? a : a - cmd;}
int _sub(int a, int b) {a -= b; return a < 0 ? a + cmd : a;};
int _mul(int a, int b) {return 1ll * a * b % cmd;}
int fpow(int a, int b) {
int res = 1;
for (; b; b >>= 1, a = _mul(a, a))
if (b & 1) res = _mul(res, a);
return res;
}
}using namespace _MoFa;
const int maxn = 500 + 5;
int n, a[maxn];
int main() {
scanf("%d", &n);
for (int i = 1; i <= n; i++) {
int x; scanf("%d", &x);
if (~x) a[x]++;
}
int ans = fpow(2, n - 1) - 1;
for (int i = 1; i <= n; i++) ans = _sub(ans, fpow(2, a[i]) - 1);
printf("%d", ans);
return 0;
}
标签:Acquisitions,return,函数,int,dfrac,Company,cmd,CF1025G,res 来源: https://www.cnblogs.com/klii/p/15914949.html