类欧几里德证明

类欧几里德
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
一道求g裸题的代码
In 2 4 3 1 3 输入a c b l r样例是求i由1~3求和i*[(2i+3)/4]向下取整
Out 9 输出1
[(21+3)/4]+2[(22+3)/4]+ 3[(2*3+3)/4]=1+2+6=9

#include <bits/stdc++.h>
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(){
    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;
}

猜你喜欢

转载自blog.csdn.net/cj1064789374/article/details/84996403