CF932Eチームワーク数論

トピック

https://codeforces.com/contest/932/problem/E

中国語のタイトル:N(1≤N≤1e9)の異なる人々がいて、そこからx(xは少なくとも1)の個人を選択して、xk(1≤k≤5000)のコストでチームタスクを完了します。すべてのチーム計画の総コストを見つけます。

導関数の4つの算術演算について:https//www.cnblogs.com/liming19680104/p/10955536.html

回答

質問要件\ sum_ {i = 0} ^ {n} C_ {n} ^ {i} i ^ {k}を描くのは簡単です。ここで、i = 0は答えに影響しません。

C_ {n} ^ {i}以下を見ると二項定理が思い浮かびます:② (x + 1)^ {n} = \ sum_ {i = 0} ^ {n} C_ {n} ^ {i} x ^ {i}

①は②と非常によく似ており、②は①よりもはるかに優れています。②を①に変更するにはどうすればよいですか?

答えは:派生を求める

②式の導関数をxで乗算されている場合、X誘導体、繰り返し乗算され、なり\ sum_ {i = 0} ^ {n} C_ {n} ^ {i} ix ^ {i}\ sum_ {i = 0} ^ {n} C_ {n} ^ {i} i ^ {2} x ^ {i}\ sum_ {i = 0} ^ {n} C_ {n} ^ {i} i ^ {3} x ^ {i}...、k回は後で再利用となる\ sum_ {i = 0} ^ {n} C_ {n} ^ {i} i ^ {k} x ^ {i}xが、それは1に等しくするために、我々は、任意に取ら数であるので、。式②の右辺がやっととなります\ sum_ {i = 0} ^ {n} C_ {n} ^ {i} i ^ {k}ので、式②の左辺の微分結果を計算するだけで答えが得られます。

②式の左側の変換プロセス:

一度:(x + 1)^ {n} \ rightarrow n(x + 1)^ {n-1} x

このとき、関数 は4つの算術演算の導関数に従ってn(x + 1)^ {n-1}バツ乗算という2つの関数になり ます。d [f(x)g(x)] = f(x)d [g(x)] + g(x)d [f(x)]

次の変換を行うことができます。n(x + 1)^ {n-1} x \ rightarrow n(x + 1)^ {n-1} x + n(n-1)(x + 1)^ {n-2} x ^ {2 }

このようにして 、a_ {j}(x + 1)^ {nj} x ^ {j}( a_ {j}この項の係数の)形式の 各項をに変更できます ja_ {j}(x + 1)^ {nj} x ^ {j} +(nj)a_ {j}(x + 1)^ {n-(j + 1)} x ^ {j + 1}

k回の変換を実行し、最大でk個のアイテムを生成しj> n、アイテムの削除はカウントされません。係数と複雑さを維持するには、dpを使用します。O(k ^ {2})

コード

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<vector>
#define ll long long
#define MAXN 5005
#define MOD 1000000007ll
using namespace std;
inline ll read(){
	ll x=0,f=1;char s=getchar();
	while((s<'0'||s>'9')&&s>0){if(s=='-')f*=-1;s=getchar();}
	while(s>='0'&&s<='9'){x=(x<<1)+(x<<3)+s-'0';s=getchar();}
	return x*f;
}
int k;
ll n,dp[MAXN],ans;
inline ll ksm(ll a,ll b,ll mo){
	ll res=1;
	for(;b;b>>=1){
		if(b&1)res=res*a%mo;
		a=a*a%mo;
	}
	return res;
}
int main()
{
	n=read(),k=read();
	dp[1]=n;
	for(int i=2;i<=k;i++)
		for(int j=i;j>0;j--)
			dp[j]=(dp[j-1]*(n-j+1)+dp[j]*j)%MOD;
	for(int i=1;i<=k;i++)
		if(n-i>=0)ans=(ans+dp[i]*ksm(2,n-i,MOD))%MOD;//令x等于1
	printf("%lld\n",ans);
	return 0;
}

 

おすすめ

転載: blog.csdn.net/weixin_43960287/article/details/108931944