其他分享
首页 > 其他分享> > [势能函数] CF1025G Company Acquisitions

[势能函数] CF1025G Company Acquisitions

作者:互联网

\(\texttt{link}\)

好神仙的科技。/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