SRM467 Div1 500 SuperSum
問題
- SuperSum(0, n) = n
- SuperSum(k, n) = SuperSum(k-1, 1) + … + SuperSum(k-1, n)
- で定義されるSuperSum(k, n)の値を求める.kは50以下,nは10億以下
解いてみた
- kが小さい場合を考えてみると
- SuperSum(1, n) = n(n+1)/2
- SuperSum(2, n) = n(n+1)(n+2)/6
- となると…
- SuperSum(k, n) = n(n+1)…(n+k)/(k+1)! か?
- 実装してみたらシステムテストに通った.
- あとで証明もちゃんと考えてみよう.
- (追記)普通にコンビネーションじゃないか…
- kが50以下ということは,他の解法もあるのかな?
#include <iostream> using namespace std; const int MOD = 1000000007; class SuperSum{ private: long long pow(int t, int p){ if(p == 0) return 1; if(p == 1) return t; long long tmp = pow(t, p/2)%MOD; tmp = (tmp*tmp)%MOD; if(p%2 == 0) return tmp; return (tmp*t)%MOD; } long long rev(int t){ return pow(t, MOD-2); } public: int calculate(int k, int n){ long long res = n; for(int i=0;i<k;i++) res = (res*(n+i+1))%MOD; for(int i=2;i<=k+1;i++) res = (res*rev(i))%MOD; return (int)res; } };