• BZOJ3157 国王奇遇记——神奇的推式子


    先膜一发Miskcoo,大佬的博客上多项式相关的非常全
    原题戳我

    题目大意

    [sumlimits_{i=1}^{n}i^mm^i ]

    题解

    设一个函数(f(i)=sumlimits_{j=1}^{n}j^im^j)
    然后貌似用一个叫扰动法(感觉就是错位相消法)的东西,算一下

    [(m-1)f(i)=sumlimits_{j=1}^{n+1}(j-1)^im^j-sumlimits_{i=1}^{n}j^im^j=n^im^{n+1}-sumlimits_{j=1}^{n}m^j[(j-1)^i-j^i] ]

    其中,((j-1)^i-j^i)可以用一波二项式展开化为(sumlimits_{k=0}^{i-1}inom{i}{k}(-1)^{i-k}j^k),回带可得

    [(m-1)f(i)=n^im^{n+1}-sumlimits_{j=1}^{n}m^jsumlimits_{k=0}^{i-1}inom{i}{k}(-1)^{i-k}j^k$$$$=n^im^{n+1}-sumlimits_{k=0}^{i-1}inom{i}{k}(-1)^{i-k}sumlimits_{j=1}^{n}j^km^j$$$$=n^im^{n+1}-sumlimits_{k=0}^{i-1}inom{i}{k}(-1)^{i-k}f(k) ]

    然后就有了一个(O(m^2))的递推做法,还有一个(O(m))的,但看起来挺麻烦的,咕了
    以下是代码,注意初值(f(0))的设置还有(m=1)时的特判

    #include <algorithm>
    #include  <iostream>
    #include   <cstdlib>
    #include   <cstring>
    #include    <cstdio>
    #include    <string>
    #include    <vector>
    #include     <cmath>
    #include     <ctime>
    #include     <queue>
    #include       <map>
    #include       <set>
    
    using namespace std;
    
    #define ull unsigned long long
    #define pii pair<int, int>
    #define uint unsigned int
    #define mii map<int, int>
    #define lbd lower_bound
    #define ubd upper_bound
    #define INF 0x3f3f3f3f
    #define IINF 0x3f3f3f3f3f3f3f3fLL
    #define vi vector<int>
    #define ll long long
    #define mp make_pair
    #define pb push_back
    #define re register
    #define il inline
    
    #define MOD 1000000007
    #define M 1000
    
    int n, m;
    int C[M+5][M+5];
    int f[M+5];
    
    int fpow(int x, int p) {
    	int ret = 1;
    	while(p) {
    		if(p&1) ret = 1LL*ret*x%MOD;
    		x = 1LL*x*x%MOD;
    		p >>= 1;
    	}
    	return ret;
    }
    
    void init() {
    	for(int i = 0; i <= m; ++i) C[i][0] = 1;
    	for(int i = 1; i <= m; ++i)
    		for(int j = 1; j <= i; ++j)
    			C[i][j] = (C[i-1][j-1]+C[i-1][j])%MOD;
            f[0] = (1LL*(fpow(m, n+1)-1)*fpow(m-1, MOD-2)%MOD-1+MOD)%MOD;
    }
    
    int main() {
    	scanf("%d%d", &n, &m);
    	if(m == 1) {
    		printf("%lld
    ", 1LL*n*(n+1)%MOD*fpow(2, MOD-2)%MOD);
    		return 0;
    	}
    	init();
    	for(int i = 1; i <= m; ++i) { // 递推
    		f[i] = 1LL*fpow(n, i)*fpow(m, n+1)%MOD;
    		for(int j = 0; j <= i-1; ++j) {
    			if((i-j)&1) f[i] = (f[i]-1LL*C[i][j]*f[j]%MOD)%MOD;
    			else f[i] = (f[i]+1LL*C[i][j]*f[j]%MOD)%MOD;
    		}
    		f[i] = (1LL*f[i]*fpow(m-1, MOD-2)%MOD+MOD)%MOD;
    	}
    	printf("%d
    ", f[m]);
            return 0;
    }
    
  • 相关阅读:
    在GitHub上删除项目后,在Android Studio上传项目依然提示project is already on github
    Android Studio 使用Intent实现页面的跳转(带参数)
    Android Studio 点击两次返回键,退出APP
    Android Studio 使用ViewPager + Fragment实现滑动菜单Tab效果 --简易版
    Eclipse 分屏显示同一个代码文件
    关于线上问题处理心得分享
    关于敏捷开发
    Python语言程序设计学习 之 了解Python
    关于测试
    C# 使用FileUpload控件上传图片,将文件转换成二进制进行存储与读取
  • 原文地址:https://www.cnblogs.com/dummyummy/p/10913073.html
Copyright © 2020-2023  润新知