Description
WYF有一个精致的k维立方体盒子(2维为正方形,3维为正方体,以此类推)。这个盒子的边长为n,里面有一个边长为n-1的盒子,边长为n-1的盒子里面还有一个边长为n-2的盒子……最里面的盒子边长为m。现在WYF想知道这n-m+1个盒子的k维体积和模p的余数。
Input
输入共一行包含4个正整数k, n, m, p。
Output
输出共一行包含1个正整数,表示n-m+1个盒子的k维体积之和模p的余数。
Sample Input
输入1:
4 2 2 97
输入2:
1 100 1 10007
Sample Output
输出1:
16
【样例说明】
边长为2的4维立方体的4维体积为16。
输出2
5050
Data Constraint
![](https://i-blog.csdnimg.cn/blog_migrate/f42e6d38a2ac055d0eaa4998e64bfbb0.png)
分析
不会数学公式,不方便打,不妨看ZZY大爷的吧
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
#include <iostream> #include <cstdio> using namespace std; typedef long long ll; const ll C=1e6; ll k,n,m,p,s[2010][2010]; ll Multi(ll a,ll b) { ll x=a%C,y=b%C,ax=a/C,ay=b/C; return (x*y%p+x*ay%p*C%p+y*ax%p*C%p+ax*ay%p*C%p*C%p)%p; } //AntiExplodeMulti ll Power(ll x,ll y) {ll ans=1;for (;y;y>>=1,x=Multi(x,x)) if (y&1) ans=Multi(ans,x);return ans;} void Pre_Process() { s[0][0]=1; for (int i=1;i<=k;++i) for (int j=1;j<=i;++j) s[i][j]=(s[i-1][j-1]+Multi(j,s[i-1][j]))%p; } ll Calc(ll x) { ll ans=0; for (int i=0;i<=k;++i) { ll pow=s[k][i]; for (ll j=x-i+1;j<=x+1;++j) pow=Multi(pow,j%(i+1)==0?j/(i+1):j); ans=(ans+pow)%p; } return ans; } int main() { scanf("%lld%lld%lld%lld",&k,&n,&m,&p); ll ans=0; if (n-m<=5000ll) for (ll i=n;i>=m;--i) ans=(ans+Power(i,k))%p; else { Pre_Process(); ans=((Calc(n)-Calc(m-1))%p+p)%p; } printf("%lld",ans); }