您的位置:首页 > 其它

WYF的盒子

2016-03-15 22:05 369 查看

Description

给出n,m,k,p,求

∑i=nmikmodp\sum_{i=n}^mi^k\mod p

Solution

用什么

首先,自然数幂求和,好多方法啊。解决自然数幂和的各种方法

由于第一类斯特林数不用中国剩余定理来对于mod操作特殊处理,所以这个好。

用前缀和思想,再加上用第一类斯特林数处理自然数幂和,然后就能过了吗。

两个数乘起来爆long long了!

怎么办。

看处理两数相乘的黑科技

注意

不要在运算的时候mod 太多次,mod的速度十分的慢啊!

Code

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<cstdio>
#define fo(i,a,b) for(i=a;i<=b;i++)
#define ll long long
using namespace std;
ll i,j,k,l,t,n,m,ans,mo;
ll s[2060][2060],f[2060];
ll qsc(ll x,ll y){
ll a1=x/1000000,a2=x%1000000,b1=y /1000000,b2=y%1000000,z=0;
z=(a1*b1%mo*1000000%mo*1000000%mo);
z=(z+a1*b2%mo*1000000%mo);
z=(z+a2*b2%mo);
z=(z+a2*b1%mo*1000000%mo);
return z%mo;
}
ll qsm(ll x,ll y){
ll z=1;
while(y!=0){
if(y&1!=0)z=qsc(z,x);
x=qsc(x,x);
y=y /2;
}
return z;
}
ll stirling(ll x){
ll i,j,l,o;
memset(f,0,sizeof(f));
if(x%2==0)f[1]=qsc(x/2,(x+1));
else f[1]=qsc((x+1)/2,x);
f[0]=x%mo;
fo(i,2,k){
l=1;
fo(j,x-i+1,x+1){
if(j%(i+1)==0)l=qsc(l,(j/(i+1)));
else l=qsc(l,j);
}
f[i]=l;
fo(j,0,i-1){
if((i+j)%2==0)o=1;else o=-1;
f[i]=(f[i]-(qsc(o*f[j],s[i][j]))+mo);
f[i]=(f[i]+mo)%mo;
}
}
return f[k]%mo;
}
int main(){
scanf("%lld%lld%lld%lld",&k,&n,&m,&mo);
if(n>m)t=n,n=m,m=t;
if(m-n<=5000){
fo(i,n,m){
ans=(ans+qsm(i,k))%mo;
}
printf("%lld\n",ans);
return 0;
}
s[0][0]=1;
fo(i,0,k)s[i][i]=1;
fo(i,1,k){
fo(j,1,i-1){
s[i][j]=(qsc(s[i-1][j],(i-1))+s[i-1][j-1])%mo;
}
}
ans=(stirling(m)-stirling(n-1)+mo)%mo;
printf("%lld\n",ans);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: