zoukankan      html  css  js  c++  java
  • CF 622 F The Sum of the k-th Powers —— 拉格朗日插值

    题目:http://codeforces.com/contest/622/problem/F

    设 f(x) = 1^k + 2^k + ... + n^k

    则 f(x) - f(x-1) = x^k

    因为差值是 k 次的,所以 f 的次数应该是 k+1;

    算出 k+2 个值就可以用拉格朗日插值求解了;

    但是 k^2 会 T;

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    int const xn=1e6+5,mod=1e9+7;
    int n,k,f[xn];
    int pw(ll a,int b)
    {
      ll ret=1;
      for(;b;b>>=1,a=(a*a)%mod)
        if(b&1)ret=(ret*a)%mod;
      return ret;
    }
    int upt(int x){while(x>=mod)x-=mod; while(x<0)x+=mod; return x;}
    int main()
    {
      scanf("%d%d",&n,&k);
      for(int i=1;i<=k+2;i++)f[i]=upt(f[i-1]+pw(i,k));//!k+1
      int sum=0;
      for(int i=1;i<=k+2;i++)
        {
          ll s1=1,s2=1;
          for(int j=1;j<=k+2;j++)
        {
          if(i==j)continue;
          s1=s1*(n-j)%mod;
          s2=s2*(i-j)%mod;
        }
          sum=(sum+s1*pw(s2,mod-2)%mod*f[i])%mod;
        }
      printf("%d
    ",upt(sum));
      return 0;
    }
    TLE

    由于 x 都是连续的,所以可以直接预处理阶乘;

    分母部分的阶乘要跳过0,比较麻烦...一开始准备先算一个值,然后每次修改,但是失败了...

    于是参考了一下 TJ,原来可以分正负两部分计算!

    分子万一乘到0怎么办?先特判一下 n<=k+2 即可;

    别忘了阶乘数组是 ll 或局部开 ll !

    代码如下:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    int const xn=1e6+5,mod=1e9+7;
    int n,k,f[xn];
    ll fac[xn];//ll
    int pw(ll a,int b)
    {
      ll ret=1;
      for(;b;b>>=1,a=(a*a)%mod)
        if(b&1)ret=(ret*a)%mod;
      return ret;
    }
    int upt(int x){while(x>=mod)x-=mod; while(x<0)x+=mod; return x;}
    ll get(int i)
    {
      if(i==k+2)return fac[i-1];
      return fac[i-1]*fac[k+2-i]%mod;
    }
    int main()
    {
      scanf("%d%d",&n,&k);
      for(int i=1;i<=k+2;i++)f[i]=upt(f[i-1]+pw(i,k));//!k+1
      if(n<=k+2){printf("%d
    ",f[n]); return 0;}//!!
      int sum=0; ll s1=1; fac[0]=1;
      for(int i=1;i<=k+2;i++)fac[i]=fac[i-1]*i%mod;
      for(int i=1;i<=k+2;i++)s1=s1*(n-i)%mod;
      //for(int i=2;i<=k+2;i++)s2=s2*(1-i)%mod;
      for(int i=1;i<=k+2;i++)
        {
          ll t1=s1*pw(n-i,mod-2)%mod;
          ll s2=pw(get(i),mod-2); 
          if((k+2-i)%2)s2=-s2;
          //if(i>1)s2=s2*pw(upt(i-1-k-2),mod-2)%mod*(i-1)%mod;
          sum=(sum+t1*s2%mod*f[i])%mod;
        }
      printf("%d
    ",upt(sum));
      return 0;
    }
  • 相关阅读:
    现代操作系统:原理与实现配套实验ChCorelab02
    损失函数:交叉熵
    什么是 AWS IoT Greengrass?
    softmax与sigmoid的关系&最大熵与极大似然估计的关系
    AWS IoT Greengrass:连接器入门
    损失函数:最小二乘法与极大似然估计法
    AWS IoT Greengrass:将密钥部署到核心
    奇异值分解(SVD)
    积性函数前缀和个人总结
    AWS IoT Greengrass:核心软件的 OTA 更新
  • 原文地址:https://www.cnblogs.com/Zinn/p/10008776.html
Copyright © 2011-2022 走看看