算是知道了扩展欧几里得这个算法了吧。。。。
转载自http://www.cnblogs.com/cyz666/
f的模板
LL S(LL k)
{
return (k*(k+1)/2ll)%MOD;
}
LL f(LL a,LL b,LL c,LL n)
{
if(!a)return 0;
if(a>=c || b>=c)
return ((a/c)*S(n)%MOD+(n+1)*(b/c)%MOD+f(a%c,b%c,c,n))%MOD;
LL m=(a*n+b)/c;
return (m*n%MOD-f(c,c-b-1,a,m-1)+MOD)%MOD;
}
g的模板
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
const int mo=1e9+7,inv2=500000004,inv6=166666668;
typedef long long LL;
int a,b,c,l,r;
struct data
{
int f,g,h;
};
data calc(int a,int b,int c,LL n)
{
data tmp;
if (!a)
{
tmp.f=tmp.g=tmp.h=0;
return tmp;
}
if (a>=c || b>=c)
{
tmp=calc(a%c,b%c,c,n);
n%=mo;
tmp.h=(tmp.h+
n*(n+1)%mo*(2*n+1)%mo*inv6%mo*(a/c)%mo*(a/c)%mo
+(n+1)*(b/c)%mo*(b/c)%mo
+(LL)2*(a/c)*tmp.g%mo
+(LL)2*(b/c)*tmp.f%mo
+n*(n+1)%mo*(a/c)%mo*(b/c))%mo;
tmp.f=(tmp.f
+n*(n+1)/2%mo*(a/c)
+(n+1)*(b/c))%mo;
tmp.g=(tmp.g
+n*(n+1)%mo*(2*n+1)%mo*inv6%mo*(a/c)
+n*(n+1)/2%mo*(b/c))%mo;
return tmp;
}
LL m=((LL)a*n+b)/c;
data nxt=calc(c,c-b-1,a,m-1);
n%=mo; m%=mo;
tmp.f=((n*m-nxt.f)%mo+mo)%mo;
tmp.g=(LL)((n*(n+1)%mo*m-nxt.f-nxt.h)%mo+mo)*inv2%mo;
tmp.h=((m*(m+1)%mo*n-(LL)2*(nxt.g+nxt.f)%mo-tmp.f)%mo+mo)%mo;
return tmp;
}
int main()
{
freopen("task.in","r",stdin); freopen("task.out","w",stdout);
scanf("%d%d%d%d%d",&a,&c,&b,&l,&r);
printf("%d\n",(calc(a,b,c,r).g-calc(a,b,c,l-1).g+mo)%mo);
return 0;
}