洛谷P4593 [TJOI2018]教科书般的亵渎 【数学】

题目链接

洛谷P4593

题解

这种神仙数学题我当然不会做。。

orz dalao

不过推导倒是挺简单

由题我们只需模拟出代价,只需使用\(S(n,k) = \sum\limits_{i = 1}^{n} i^{k}\)这样的前缀和计算

我不知道怎么来的这样一个公式【如果有那位dalao知道欢迎留言】:

\[(n + 1)^{k + 1} - n^{k + 1} = \sum\limits_{i = 1}^{k + 1} {k + 1\choose i}n^{k + 1 - i}\]

我们发现这个公式右侧涵盖了所有\(n^i\)的项,如果我们将所有\(n\)枚举出来,将会的得到:

\[
\begin{aligned}
(n + 1)^{k + 1} - n^{k + 1} &= \sum\limits_{i = 1}^{k + 1} {k + 1\choose i}n^{k + 1 - i} \n^{k + 1} - (n - 1)^{k + 1} &= \sum\limits_{i = 1}^{k + 1} {k + 1\choose i}(n - 1)^{k + 1 - i} \......... \2^{k + 1} - 1^{k + 1} &= \sum\limits_{i = 1}^{k + 1} {k + 1\choose i}1^{k + 1 - i} \\end{aligned}
\]

全部相加,得到:

\[(n + 1)^{k + 1} - 1 = \sum\limits_{i= 1}^{k + 1} {k + 1 \choose i} S(n,k + 1 - i)\]

取出\(S(n,k)\)

\[S(n,k) = \frac{(n + 1)^{k + 1} - 1 - \sum\limits_{i = 2}^{k + 1}{k + 1 \choose i} S(n,k + 1 - i)}{k + 1}\]

发现就可以\(O(k^2)\)递推了

由于模拟也是\(O(k^2)\)的

所以最终复杂度\(O(k^4)\)

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<map>
#define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)
#define REP(i,n) for (int i = 1; i <= (n); i++)
#define mp(a,b) make_pair<int,int>(a,b)
#define cls(s) memset(s,0,sizeof(s))
#define cp pair<int,int>
#define LL long long int
using namespace std;
const int maxn = 105,maxm = 100005,INF = 1000000000,P = 1000000007;
inline LL read(){
    LL out = 0,flag = 1; char c = getchar();
    while (c < 48 || c > 57){if (c == ‘-‘) flag = -1; c = getchar();}
    while (c >= 48 && c <= 57){out = (out << 3) + (out << 1) + c - 48; c = getchar();}
    return out * flag;
}
int n,m,K,fac[maxn],fv[maxn],inv[maxn];
LL a[maxn];
void init(){
    fac[0] = fac[1] = fv[0] = fv[1] = inv[0] = inv[1] = 1;
    for (int i = 2; i < maxn; i++){
        fac[i] = 1ll * fac[i - 1] * i % P;
        inv[i] = 1ll * (P - P / i) * inv[P % i] % P;
        fv[i] = 1ll * fv[i - 1] * inv[i] % P;
    }
}
LL C(LL n,LL m){
    return 1ll * fac[n] * fv[m] % P * fv[n - m] % P;
}
LL qpow(LL a,LL b){
    LL ans = 1; a %= P;
    for (; b; b >>= 1,a = a * a % P)
        if (b & 1) ans = ans * a % P;
    return ans;
}
LL f[maxn];
LL S(LL n,LL k){
    if (!n) return 0;
    f[0] = n;
    for (int i = 1; i <= k; i++){
        LL tmp = 0;
        for (int j = 2; j <= i + 1; j++)
            tmp = (tmp + C(i + 1,j) * f[i + 1 - j]) % P;
        f[i] = (((qpow(n + 1,i + 1) - 1) % P - tmp) % P + P) % P * inv[i + 1] % P;
    }
    return f[k];
}
LL b[maxn];
int main(){
    init();
    int T = read();
    while (T--){
        n = read(); m = read(); K = m + 1;
        REP(i,m) a[i] = read(); a[K] = n + 1;
        sort(a + 1,a + 1 + K);
        LL ans = 0;
        for (int i = 0; i <= m; i++){
            for (int j = i; j <= m; j++){
                ans = ((ans + (S(a[j + 1] - 1,K) - S(a[j],K)) % P) % P + P) % P;
            }
            LL len = a[i + 1] - a[i];
            for (int j = i + 1; j <= K; j++) a[j] -= len;
        }
        printf("%lld\n",ans);
    }
    return 0;
}

原文地址:https://www.cnblogs.com/Mychael/p/9052067.html

时间: 2024-08-29 21:47:15

洛谷P4593 [TJOI2018]教科书般的亵渎 【数学】的相关文章

P4593 [TJOI2018]教科书般的亵渎(拉格朗日插值)

传送门 首先所有亵渎的张数\(k=m+1\),我们考虑每一次使用亵渎,都是一堆\(i^k\)之和减去那几个没有出现过的\(j^k\),对于没有出现过的我们可以直接快速幂处理并减去,所以现在的问题就是如果求\(\sum_{i=1}^ni^k\) 据attack巨巨说,上面那个东西是一个以\(n\)为自变量的\(k+1\)次多项式,因为我们只需要单点求值,所以可以先求出\(k+2\)个值,然后就可以用拉格朗日插值来每次\(O(k)\)地求出一个值 至于这里是如何优化到\(O(k)\)的,本来拉格朗日

Luogu P4593 [TJOI2018]教科书般的亵渎

亵渎终于离开标准了,然而铺场快攻也变少了 给一个大力枚举(无任何性质)+艹出自然数幂和的方法,但是复杂度极限是\(O(k^4)\)的,不过跑的好快233 首先简单数学分析可以得出\(k=m+1\),因为每多一个空缺就会打断一张亵渎的连击 那么我们考虑对于每个空缺求出答案,发现此时所求答案必定为一段自然数幂和并且减去空缺的数字幂 发现数据范围\(m\le 50\),那么我们直接暴力求出所有连续的段,然后大力枚举这一段开始最低的怪的血量 空缺不妨暴力枚举,区间内的自然数幂和直接差分一下,那么我们只要

P4593 [TJOI2018]教科书般的亵渎(拉格朗日插值)

题目描述 小豆喜欢玩游戏,现在他在玩一个游戏遇到这样的场面,每个怪的血量为aia_iai?,且每个怪物血量均不相同,小豆手里有无限张“亵渎”.亵渎的效果是对所有的怪造成111点伤害,如果有怪死亡,则再次施放该法术.我们认为血量为000怪物死亡. 小豆使用一张 “亵渎”会获得一定的分数,分数计算如下,在使用一张“亵渎”之后,每一个被亵渎造成伤害的怪会产生xkx^kxk,其中xxx是造成伤害前怪的血量为xxx和需要杀死所有怪物所需的“亵渎”的张数kkk. 输入输出格式 输入格式: 第一行输入一个TT

[TJOI2018]教科书般的亵渎

传送门 做这道题的时候超级有画面感-- 这道题其实不是很难--只要掌握了结论就不是什么问题,不过我因为推错了还是做了好长时间-- 题目其实就是要求你重复多次求 \[\sum_{i=1}^n i^{m+1}\] 以前有大神写论文告诉我们,这个式子是一个以\(n\)为自变量的\(k+1\)(\(k\)是指数)次多项式,那么我们就可以用拉格朗日插值求一下. 这题的数据范围很小,所以其实可以不使用\(O(n)\)的算法,直接普通的求也是可以过的.然后注意要删去不存在的血量给答案的贡献,因为每次释放亵渎以

【bzoj5339】[TJOI2018]教科书般的亵渎(拉格朗日插值/第二类斯特林数)

传送门 题意: 一开始有很多怪兽,每个怪兽的血量在\(1\)到\(n\)之间且各不相同,\(n\leq 10^{13}\). 然后有\(m\)种没有出现的血量,\(m\leq 50\). 现在有个人可以使用魔法卡片,使用一张会使得所有的怪兽掉一点血,如果有怪兽死亡,则继续施展魔法. 这个人能够获得一定的分数,分数计算如下,每一次使用卡片前,假设一个怪兽血量为\(x\),那么获得\(x^k\)的分数.\(k\)为杀死所有怪兽需要的卡片数量. 求最后总的分数. 思路: 因为\(m\)很小,那么我们可

洛谷P1061 Jam的计数法 数学

洛谷P1061 Jam的计数法 数学 已知一个字符串 其 均有 s--t构成 且字符串要求 s[ i ]<s[ j ] i < j 已知一个字符串 求按字典序排列 的后5个字符串 1. 对于一个字符串已知,我们如何求他的下一个字符串呢? 我们可以从低位枚举到高位,找到第一个可以增长的数,然后增长2.同时把自己后面的串改为字典序最小,即这一位为上一位 + 1 这样字典序就最小了 1 #include <cstdio> 2 #include <cmath> 3 #inclu

洛谷P1080 国王游戏 高精度 贪心 数学推公式

洛谷P1080 国王游戏        数学推公式      高精度    贪心 然而这并不是我打出来的,抄题解... 将左手与右手的乘积从小到大排序,然后计算求最大值即可.(需要高精度) 证明: 1)知道,如果相邻的两个人交换位置,只会影响到这两个人的值,不会影响他人 2)假设相邻的两个人i, i + 1.设A[i] B[i] <= A[i + 1] B[i + 1],i之前所有人的左手乘积为S. 则,ans1 = max{S / B[i], S * A[i] / B[i + 1]} 若交换

教科书般的亵渎

环境里有 $n$ 个怪物,他们的生命值用一个正整数表示.现在,你可以使用两种魔法,对怪物进行攻击.当怪物的生命值小于等于 $0$ 时,他便被消灭了. 魔法箭,对摸个生物造成 $k$ 点伤害,对一个生物最多使用一次,但没有使用次数限制. 亵渎,对所有生物造成一点伤害,如果杀死了某个生物,则继续自动重新使用该法术.只能主动使用一次,且必须最后使用. 请问,最多能消灭多少个怪物?亵渎法术最多能释放几次? 输入格式 第一行两个整数 $n$ 和 $k$ ,表示怪物的数量和法术的伤害.第二行 $n$ 个正整

计蒜客 教科书般的亵渎

Description: 环境里有 nn 个怪物,他们的生命值用一个正整数表示.现在,你可以使用两种魔法,对怪物进行攻击.当怪物的生命值小于等于 00 时,他便被消灭了. 魔法箭,对摸个生物造成 kk 点伤害,对一个生物最多使用一次,但没有使用次数限制. 亵渎,对所有生物造成一点伤害,如果杀死了某个生物,则继续自动重新使用该法术.只能主动使用一次,且必须最后使用. 请问,最多能消灭多少个怪物?亵渎法术最多能释放几次? Input: 第一行两个整数 nn 和 kk ,表示怪物的数量和法术的伤害.第