zoukankan      html  css  js  c++  java
  • 51NOD 1258 序列求和 V4

    基准时间限制:8 秒 空间限制:131072 KB 分值: 1280 难度:9级算法题
    Discription
    T(n) = n^k,S(n) = T(1) + T(2) + ...... T(n)。给出n和k,求S(n)。
     
    例如k = 2,n = 5,S(n) = 1^2 + 2^2 + 3^2 + 4^2 + 5^2 = 55。
    由于结果很大,输出S(n) Mod 1000000007的结果即可。
    Input
    第1行:一个数T,表示后面用作输入测试的数的数量。(1 <= T <= 500)
    第2 - T + 1行:每行2个数,N, K中间用空格分割。(1 <= N <= 10^18, 1 <= K <= 50000)
    Output
    共T行,对应S(n) Mod 1000000007的结果。
    Input示例
    3
    5 3
    4 2
    4 1
    Output示例
    225
    30
    10

    拉格朗日插值模板题,但是要注意当 N%1e9+7 <= L 的时候,插的值里面只有一项不是0,这时候要特判一下。。
    然后我们就水了1280分

    /*
        自然幂数和的拉格朗日插值做法。
    	假设我们求的是k次前缀和,那么就是一个k+1次多项式,
    	于是我们带k+2个点进去差值就好了。
    	
    	 f(x) = ∑y[i] * π(x-x[j]) / π(x[i]-x[j]) 
    */
    #include<bits/stdc++.h>
    #define ll long long
    const int ha=1000000007;
    using namespace std;
    int T,K,L,ans=0,S;
    int base,jc[50020];
    ll N; 
    
    inline int add(int x,int y){
    	x+=y;
    	return x>=ha?x-ha:x;
    }
    
    inline int ksm(int x,int y){
    	int an=1;
    	for(;y;y>>=1,x=x*(ll)x%ha) if(y&1) an=an*(ll)x%ha;
    	return an;
    }
    
    inline void solve(){
    	ans=S=0,base=1;
    	int ops=N%ha;
    	for(int i=1;i<=L;i++){
    		ops=add(ops,ha-1);
    		base=base*(ll)ops%ha;
    	}
    	
    	if(!base){
    		ops=N%ha;
    		base=1;
    		for(int i=1;i<=L;i++){
    			ops=add(ops,ha-1);
    			S=add(S,ksm(i,K));
    			if(ops) base=base*(ll)ops%ha;
    			else ans=S*(ll)jc[i-1]%ha*(ll)jc[L-i]%ha*(ll)(((L-i)&1)?ha-1:1)%ha;
    		}
    		ans=ans*(ll)base%ha;
    	}
    	else{
    		ops=N%ha;
    		for(int i=1,now;i<=L;i++){
    			ops=add(ops,ha-1);
    			S=add(S,ksm(i,K));
    			now=base*(ll)ksm(ops,ha-2)%ha*(ll)jc[i-1]%ha*(ll)jc[L-i]%ha;
    			if((L-i)&1) now=now*(ll)(ha-1)%ha;
    			ans=add(ans,S*(ll)now%ha);
    		}
    	}
    }
    
    int main(){
    	jc[0]=1;
    	for(int i=1;i<=50010;i++) jc[i]=jc[i-1]*(ll)i%ha;
    	for(int i=1;i<=50010;i++) jc[i]=ksm(jc[i],ha-2);
    	
    	scanf("%d",&T);
    	while(T--){
    		scanf("%lld%d",&N,&K),L=K+2;
    		solve();
    		printf("%d
    ",ans);
    	}
    	
    	return 0;
    }
    
    
    

      

     
  • 相关阅读:
    MyBatis入门基础
    复制复杂链表
    二叉树中和为某一值的所有路径
    树的层次遍历
    Statement, PreparedStatement和CallableStatement的区别
    JSP有哪些动作?
    latex 输入矩阵
    Struts简单入门实例
    在Eclipse里面配置Struts2
    Windows使用Github
  • 原文地址:https://www.cnblogs.com/JYYHH/p/8545427.html
Copyright © 2011-2022 走看看