zoukankan      html  css  js  c++  java
  • Codeforces 622 F. The Sum of the k-th Powers

    ## [$>Codeforces space 622 F. The Sum of the k-th Powers<$](http://codeforces.com/problemset/problem/622/F)

    题目大意 : 给出 (n, k),求 (sum_{i=1}^{n} i^k)(10^9 +7) 取模的值

    (1 leq n leq 10^9, 0 leq k leq 10^6)

    解题思路 :

    考虑 (k) 比较大,且模数不太好 (NTT),于是考虑插值做法, 学习了一波插值之后,发现就是个板子题 (雾)

    拉格朗日插值:

    对于 (n) 个点值表达,可以确定一个 (n - 1) 次的多项式,考虑已知点值怎么构造这个多项式

    如果对于第 (i) 个点值,能够构造出这么一个多项式 (f_i(x)) ,将每一个点值表达 (j) 带进去的结果如下

    [f_i (x) = egin{cases} y_i , & ext{if $ i= j$} \ 0. \, & ext{otherwise} end{cases} ]

    那么最终的多项式 (F(x) = sum_{i=1}^{n} f_i(x))

    通过贺资料发现当 $f_i(x) = y_i imes prod_{j=1, j eq i}^{n} frac{x-x_j}{x_i-x_j} $ 时即可满足条件,不妨证明一下为什么

    考虑分子部分,如果带进去的 (x eq x_i) 那么当 (j = i) 的时候分子是 (0),结果也是 (0)

    考虑分母部分,如果 (x = x_i) 那么分子就等于分母,且分子分母都不存在 (0) ,所以结果就是 (y_i)

    大力观察题面发现,(k) 次幂的前缀和一定能用一个 (k + 1) 次的多项式来表示,不妨递推出 (x = 1 .. (k+2)) 时的点值表示直接做插值

    那么第 (n) 项的答案就等于 $F(n) = sum y_i imes prod_{j=1, j eq i}^{k+2} frac{n-x_j}{x_i-x_j} $

    因为 (x_i = i) ,所以 (F(n) = sum y_i imes prod_{j=1, j eq i}^{k+2} frac{n-j}{i-j}), 后面部分也就是 (frac{(n-1) imes(n-2) imes.. imes(n-k-2)}{(n-i) imes(i-1)! imes(n-i)! imes (-1)^{n-i}})

    那么阶乘与处理一下枚举一下 (i) 即可,注意特判一下 (i = n) 的情况不能直接除,应该记一个没有 ((n-i)) 这一项的答案


    /*program by mangoyang*/
    #include<bits/stdc++.h>
    #define inf (0x7f7f7f7f)
    #define Max(a, b) ((a) > (b) ? (a) : (b))
    #define Min(a, b) ((a) < (b) ? (a) : (b))
    typedef long long ll;
    using namespace std;
    template <class T>
    inline void read(T &x){
        int f = 0, ch = 0; x = 0;
        for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = 1;
        for(; isdigit(ch); ch = getchar()) x = x * 10 + ch - 48;
        if(f) x = -x;
    }
    #define int ll
    int js[2000005], n, k;
    const int Mod = 1000000007; 
    inline int Pow(int a, int b){
    	int ans = 1;
    	for(; b; b >>= 1, a = a * a % Mod)
    		if(b & 1) ans = ans * a % Mod;
    	return ans;
    }
    inline int Inv(int x){ return Pow((x + Mod) % Mod, Mod - 2); } 
    main(){
    	int res = 1, res2 = 1; read(n), read(k), js[0] = 1; 
    	for(int i = 1; i <= k + 2; i++){
    		js[i] = (js[i-1] * i) % Mod;
    		res = (res * (n - i) + Mod) % Mod;
    		if(i != n) res2 = (res2 * (n - i) % Mod + Mod) % Mod;
    	}
    	int now = 0, ans = 0;
    	for(int i = 1; i <= k + 2; i++){
    		now = (now + Pow(i, k)) % Mod;
    		int A = (i != n) ? res * Inv(n - i) % Mod : res2;
    		int B = js[i-1] * js[k+2-i] % Mod;
    		if((k + 2 - i) & 1) B = (-B + Mod) % Mod;
    		ans = (ans + now * (A * Inv(B) % Mod) % Mod) % Mod;
    	}
    	cout << (ans % Mod + Mod) % Mod; 
    	return 0;
    }
    
  • 相关阅读:
    【带着canvas去流浪(5)】绘制K线图
    【带着canvas去流浪(4)】绘制散点图
    【带着canvas去流浪】 (3)绘制饼图
    Mybatis缓存(1)--------系统缓存及简单配置介绍
    this引用逃逸
    MySQL优化(1)--------常用的优化步骤
    Java的内存模型
    Java Generator
    深入理解Java重载与重写
    对象的自我救赎
  • 原文地址:https://www.cnblogs.com/mangoyang/p/9398179.html
Copyright © 2011-2022 走看看