2019牛客暑期多校9I:KM and M【类欧几里得模板】

题目:

2019牛客暑假多校9I:KM and M

题意:

输入N,M,求下列式子的值:

笔记:

考虑对M的每一位算贡献,假设M的第x位为1,那么计算这一位的贡献就等价于计算KM中有多少个数的第x位为1,计算一个数第x位的值是多少可以这样计算:(v>>x) - (v>>(x+1))*2,那么第x位的贡献为:

=2^x\sum_{k=1}^{N}\left \lfloor \frac{km}{2^x} \right \rfloor-2\left \lfloor \frac{km}{2^{x+1}} \right \rfloor

=2^x(\sum_{k=1}^{N}\left \lfloor \frac{km}{2^x} \right \rfloor-2\sum_{k=1}^{N}\left \lfloor \frac{km}{2^{x+1}} \right \rfloor)

上面求和式就是类欧几里得的模板

类欧几里得的详细讲解

代码:

#include 

using namespace std;
typedef __int128 LL;
const int mod = 1e9+7;
const int inv2 = 500000004;
inline LL read(){
    LL x = 0,f = 1; char c = getchar();
    while(!isdigit(c)){if(c=='-') f=-1;c=getchar();}
    while(isdigit(c)){x=x*10+(c-'0');c = getchar();}
    return x*f;
}
inline void write(LL x){
    if(x < 0) putchar('-'),x = -x;
    if(x > 9) write(x/10);
    putchar(x%10+'0');
}
LL solve(LL a,LL b,LL c,LL n){         //计算(a*0+b)/c+(a*1+b)/c+...+(a*n+b)/c
    if(a == 0) return b/c%mod*(n+1)%mod;
    if(a>=c || b>=c) return solve(a%c,b%c,c,n)+n%mod*(n+1)%mod*inv2%mod*(a/c)%mod+(n+1)%mod*(b/c)%mod;
    LL m = (a*n+b)/c;
    return (n%mod*m%mod-solve(c,c-b-1,a,m-1)+mod)%mod;
}
int main(){
    LL n,m,ans = 0;n = read(),m = read();
    for(int i = 0;i < 50;++i){
        if(m&(1ll<= mod) ans -= mod;
        }
    }
    write((ans%mod+mod)%mod);
    return 0;
}

 

你可能感兴趣的:(模板,2019牛客暑假多校训练营,类欧几里得)