【类欧几里得】推导过程

本文详细介绍了类欧几里得算法在HDU 6275 Mod, Xor and Everything问题中的应用,通过三个部分F(a,b,c,n)、g(a,b,c,n)和h(a,b,c,n)的推导过程,阐述如何解决模运算与异或问题。文章通过举例和不等式求和的思想,辅助理解算法细节,并提供了相关的代码实现。" 72935442,6285501,文本相似度计算:欧氏距离、余弦相似度、Jaccard与编辑距离解析,"['自然语言处理', '文本分析', '算法', '数据挖掘', '机器学习']

参考博客:类欧几里得算法小结

例题:HDU 6275 Mod, Xor and Everything


题目描述

You are given an integer n.
You are required to calculate (n mod 1) xor (n mod 2) xor ... xor (n mod (n - 1)) xor (n mod n).
The “xor” operation means “exclusive OR”.

输入

The first line contains an integer T (1≤T≤5) representing the number of test cases.
For each test case, there is an integer n (1≤n≤1012) in one line.

输出

For each test case, print the answer in one line.


推导过程主要参考以上博客:

但是有些细节我觉得自己还是不太明白,自己重新写一次博客加深印象!!!!

1、F(a,b,c,n)

\large f(a,b,c,n) = \sum_{i=0}^n\left \lfloor \frac{ai+b}{c}\right \rfloor

1、当  a>=c   或者 b>=c 时:

(此时,a和b都可以分成  整除部分  和  余数部分  表示 ):

\large f(a,b,c,n) = \sum_{i=0}^n (\left \lfloor \frac{a\%c*i+b\%c}{c} \right \rfloor +\left \lfloor \frac{a}{c} \right \rfloor *i+\left \lfloor \frac{b}{c} \right \rfloor )

\large =\sum_{i=0}^n \left \lfloor \frac{a\%c*i+b\%c}{c} \right \rfloor +\frac{n*(n+1)}{2}*\left \lfloor \frac{a}{c} \right \rfloor +(n+1)\left \lfloor \frac{b}{c} \right \rfloor

\large =f(a\%c,b\%c,c,n)+\frac{n*(n+1)}{2}*\left \lfloor \frac{a}{c} \right \rfloor +(n+1)\left \lfloor \frac{b}{c} \right \rfloor


2、当  a<c 并且 b<c 时:

在推导之前先给大家一个思想用不等式求和的方式更换一个数:

譬如:

\large \sum_{i=0}^{n}i=\sum_{i=0}^{n}\sum_{j=1}^{n}(i\geq j)

左边:   等差数列求和 , 右边:    i 分解成从1~i 个1累加

i=1时:  j = 1 满足条件.                      i = 1                    = 1

i=2时:  j = 1 , 2 满足条件                  i = 1 + 1              = 2

i=3时:  j = 1 , 2 , 3 满足条件             i = 1 + 1 + 1        = 3

i=4时:  j = 1 , 2 , 3 , 4满足条件         i = 1 + 1 + 1 + 1  = 4


开始推导:

\large m=\left \lfloor \frac{a*n+b}{c}\right \rfloor

\large f(a,b,c,n) = \sum_{i=0}^{n} \sum_{j=1}^{m}(\left \lfloor \frac{a*i+b}{c} \right \rfloor\geq j)

换元法:令 k = j-1 , 因为变量名字可以换回来,所以 j = j - 1 

\large f(a,b,c,n) = \sum_{i=0}^{n} \sum_{j=0}^{m-1}(\left \lfloor \frac{a*i+b}{c} \right \rfloor\geq (j+1))

符号两边同时乘以C 不改变 符号方向:同时满足以下式子:

\large (j+1) \leq \left \lfloor \frac{a*i+b}{c} \right \rfloor \leq\frac{a*i+b}{c}

把在乘法过程把下取整符号去掉

\large f(a,b,c,n) = \sum_{i=0}^{n} \sum_{j=0}^{m-1}( a*i+b\geq cj+c)

把≥变成>

\large f(a,b,c,n) = \sum_{i=0}^{n} \sum_{j=0}^{m-1}( a*i+b +1> cj+c)

移项作除法得到:

\large f(a,b,c,n) = \sum_{i=0}^{n} \sum_{j=0}^{m-1}( i> \frac{cj+c-b-1}{a})

需要用下取整来规范

∵下取整左边变小

∴不改变不等号方向

\large f(a,b,c,n) = \sum_{i=0}^{n} \sum_{j=0}^{m-1}( i> \left \lfloor \frac{cj+c-b-1}{a} \right \rfloor)

交换两个求和次序,不改变结果

\large f(a,b,c,n) = \sum_{j=0}^{m-1}\sum_{i=0}^{n}( i> \left \lfloor \frac{cj+c-b-1}{a} \right \rfloor)

当i >=[ (cj+c-b-1) / (a) ] +1 为真,

∴起点是:[ (cj+c-b-1) / (a) ] +1 , 终点是:n

共有n - [ (cj+c-b-1) / (a) ] 项,前缀和

\large f(a,b,c,n) = \sum_{j=0}^{m-1}( n-\left \lfloor \frac{cj+c-b-1}{a} \right \rfloor)

 

\large f(a,b,c,n) = n*m-\sum_{j=0}^{m-1}( \left \lfloor \frac{cj+c-b-1}{a} \right \rfloor)

 

形如:   \large f(a,b,c,n) = \sum_{i=0}^n\left \lfloor \frac{ai+b}{c}\right \rfloor  进行类比

 

\large f(a,b,c,n) = n*m-f(c,c-b-1,a,m-1)

 


2、g(a,b,c,n)

\large g(a,b,c,n) = \sum_{i=0}^{n}i*\left \lfloor \frac{ai+b}{c} \right \rfloor


1、当 a>=c 或者 b>=c 时:

\large g(a,b,c,n) = \sum_{i=0}^{n}i*\left \lfloor \frac{ai+b}{c} \right \rfloor

\large \sum_{i=0}^{n}i*\left \lfloor \frac{ai+b}{c} \right \rfloor=\sum_{i=0}^{n} i*(\left \lfloor \frac{a\%c*i+b\%c}{c} \right \rfloor + \left \lfloor \frac{a}{c}\right \rfloor*i+\left \lfloor \frac{b}{c} \right \rfloor)

=\sum_{i=0}^{n}i*\left \lfloor \frac{a\%c*i+b\%c}{c} \right \rfloor+\frac{n*(n+1)*(2n+1)}{6}*\left \lfloor \frac{a}{c} \right \rfloor + \frac{n*(n+1)}{2}\left \lfloor \frac{b}{c} \right \rfloor

=g(a\%c,b\%c,c,n)+\frac{n*(n+1)*(2n+1)}{6}*\left \lfloor \frac{a}{c} \right \rfloor + \frac{n*(n+1)}{2}\left \lfloor \frac{b}{c} \right \rfloor


2、当 a<c 且 b<c 时 ,

\large m=\left \lfloor \frac{an+b}{c} \right \rfloor

\large g(a,b,c,n) = \sum_{i=0}^{n}i*\left \lfloor \frac{ai+b}{c} \right \rfloor

分解成不等式累加的形式

\large g(a,b,c,n) = \sum_{i=0}^{n}i\sum_{j=1}^{m}(\left \lfloor \frac{ai+b}{c} \right \rfloor \geq j )

换元:k=j-1,最后把 j = k 换回来

\large =\sum_{i=0}^{n}i\sum_{j=0}^{m-1}(\left \lfloor \frac{ai+b}{c} \right \rfloor> j+1)

省略了一些过程,首先左右乘以c(去掉下取整符号),移项,两边同除以a,添加下取整符号

\large =\sum_{i=0}^{n}i\sum_{j=0}^{m-1}( i > \left \lfloor \frac{cj+c-b-1}{a}\right \rfloor)

到了整个化简g的最难的一步了!!!

涉及等差数列求和:

\large =\sum_{j=0}^{m-1}\sum_{i=0}^{n}i*( i > \left \lfloor \frac{cj+c-b-1}{a}\right \rfloor)

当 i >= [ (cj+c-b-1) / a ] + 1 为真 

起点为:i = [ (cj+c-b-1) / a ] + 1  ,终点为:n

当在该区间内时才统计i的求和的值:

所以这个就是等差数列求和

 

首项为:[ (cj+c-b-1) / a ] + 1   

公差为:1 

共有 n- [ (cj+c-b-1) / a ] 项


\large \sum_{j=0}^{m-1}\frac{(n+(\left \lfloor \frac{cj+c-b-1}{a} \right \rfloor +1))(n-\left \lfloor \frac{cj+c-b-1}{a} \right \rfloor)}{2}

\large \frac{1}{2}\sum_{j=0}^{m-1}(n^2+n-\left \lfloor \frac{cj+c-b-1}{a} \right \rfloor^2-\left \lfloor \frac{cj+c-b-1}{a} \right \rfloor)

\large \frac{1}{2}(mn^2+mn-h(c,c-b-1,a,m-1)-f(c,c-b-1,a,m-1))


 

3、h(a,b,c,n)

\large h(a,b,c,n)=\sum_{i=0}^{n}\left \lfloor \frac{ai+b}{c} \right \rfloor^2

1、当  a>=c  或 b>=c 

\large h(a,b,c,n) = \sum_{i=0}^{n}(\frac{a\%c*i+b\%c}{c}+(\left \lfloor \frac{a}{c} \right \rfloor *i)+\left \lfloor \frac{b}{c} \right \rfloor )^2

=h(a\%c,b\%c,c,n)+\frac{n(n+1)*(2n+1)}{6}\left \lfloor \frac{a}{c} \right \rfloor^2+(n+1)\left \lfloor \frac{b}{c} \right \rfloor^2+2\left \lfloor \frac{b}{c} \right \rfloor *f(a\%c,b\%c,c,n)+2\left \lfloor \frac{a}{c} \right \rfloor g(a\%c,b\%c,c,n)+(n(n+1)\left \lfloor \frac{a}{c} \right \rfloor \left \lfloor \frac{b}{c} \right \rfloor )

 


2、a<c  且  b<c 时


在推导之前引入一个等价代换:

\large t^2=2*\frac{t(t+1)}{2}-t=(2\sum_{i=0}^{t}i)-t


\large h(a,b,c,n)=\sum_{i=0}^{n}(\left \lfloor \frac{ai+b}{c} \right \rfloor )^2

\large =\sum_{i=0}^{n}[2*\sum_{j=0}^{\frac{ai+b}{c}}j-\frac{ai+b}{c}]


\large m=\frac{an+b}{c}

此时需要分两部分来讨论:后面显然是f(a,b,c,n),主要是看前半段

\large =2\sum_{i=0}^{n}\sum_{j=1}^{\frac{ai+b}{c}}j-f(a,b,c,n)

注意看这一步,把第二个求和符号的  结束  位置 变成常量


比如:

\large \sum_{i=0}^n\sum_{j=1}^ij=\sum_{i=0}^n\sum_{j=1}^nj*(j\leq i)

只看第二个求和符号,

i =1 时 , j = 1

i =2 时,  j = 1 + 2

i =3 时,  j = 1 + 2 + 3

等价于,

j ~[1,n] ,当( j <= i )时,这个情况才被考虑.

所以就是:

\large \sum_{i=0}^n\sum_{j=1}^ij=\sum_{i=0}^n\sum_{j=1}^nj*(j\leq i)


通过上面的式子进行照葫芦画瓢:

\large =\sum_{i=0}^{n}2\sum_{j=1}^{m}j*(j \leq \left \lfloor \frac{ai+b}{c} \right \rfloor )-f(a,b,c,n)

换元法:k=j+1 ,再用 j = k 换回来

\large =\sum_{i=0}^{n}2\sum_{j=0}^{m-1}(j+1)(j+1 \leq \left \lfloor \frac{ai+b}{c} \right \rfloor )-f(a,b,c,n)

省略了一些过程,首先左右乘以c(去掉下取整符号),移项,两边同除以a,添加下取整符号

\large =2\sum_{i=0}^{n}\sum_{j=0}^{m-1}(j+1)(i>\left \lfloor \frac{cj+c-b-1}{a} \right \rfloor )-f(a,b,c,n)

交换求和次序

\large =2\sum_{j=0}^{m-1}\sum_{i=0}^{n}(j+1)(i>\left \lfloor \frac{cj+c-b-1}{a} \right \rfloor )-f(a,b,c,n)


起点是: \large \left \lfloor \frac{cj+c-b-1}{a} \right \rfloor , 终点是:\large n

前缀和求出:

\large \sum_{i=0}^{n}(i>\left \lfloor \frac{cj+c-b-1}{a} \right \rfloor ) = n-\left \lfloor \frac{cj+c-b-1}{a} \right \rfloor


\large h(a,b,c,n)=2\sum_{j=0}^{m-1}(j+1)(n-\left \lfloor \frac{cj+c-b-1}{a} \right \rfloor )-f(a,b,c,n)

=2\sum_{j=0}^{m-1}(n*j-j\left \lfloor \frac{cj+c-b-1}{a}\right \rfloor +n-\left \lfloor \frac{cj+c-b-1}{a} \right \rfloor)-f(a,b,c,n)

=2*(\frac{nm(m-1)}{2}-g(c,c-b-1,a,m-1)+mn-f(c,c-b-1,a,m-1))  \large -f(a,b,c,n)

=nm^2+mn-2g(c,c-b-1,a,m-1)-2f(c,c-b-1,a,m-1))-f(a,b,c,n)


 

最后代码是从参考博客那里拿过来的.

dong likegcd(ll a,ll b,ll c,ll n){
    if (!a){
        gjx.f=gjx.g=gjx.h=0;
        return gjx;
    }
    if (a>=c||b>=c){
        zlt=likegcd(a%c,b%c,c,n);
        gjx.f=((ll)(a/c)*n%mo*(n+1)%mo*ni2%mo+(ll)(b/c)*(n+1)%mo)%mo;
        (gjx.f+=zlt.f)%=mo;
        gjx.g=((ll)(a/c)*n%mo*(n+1)%mo*(2*n+1)%mo*ni6%mo+(ll)(b/c)*(n+1)%mo*n%mo*ni2%mo)%mo;
        (gjx.g+=zlt.g)%=mo;
        gjx.h=(ll)(a/c)*(a/c)%mo*n%mo*(n+1)%mo*(2*n+1)%mo*ni6%mo;
        (gjx.h+=(ll)(b/c)*(b/c)%mo*(n+1)%mo)%=mo;
        (gjx.h+=(ll)(a/c)*(b/c)%mo*n%mo*(n+1)%mo)%=mo;
        (gjx.h+=(ll)2*(a/c)%mo*zlt.g%mo)%=mo;
        (gjx.h+=(ll)2*(b/c)%mo*zlt.f%mo)%=mo;
        (gjx.h+=zlt.h)%=mo;
        return gjx;
    }
    ll m=((ll)a*n+(ll)b)/(ll)c;
    zlt=likegcd(c,c-b-1,a,m-1);
    gjx.f=((ll)n*m%mo-(ll)zlt.f)%mo;
    gjx.g=((ll)(n+1)*n%mo*m%mo-(ll)zlt.f-(ll)zlt.h)%mo;
    gjx.g=(ll)gjx.g*ni2%mo;
    gjx.h=((ll)n*m%mo*(m+1)%mo-(ll)2*zlt.g%mo-(ll)2*zlt.f%mo-(ll)gjx.f)%mo;
    return gjx;
}

 

例题:HDU 6275 Mod, Xor and Everything


题目描述

You are given an integer n.
You are required to calculate (n mod 1) xor (n mod 2) xor ... xor (n mod (n - 1)) xor (n mod n).
The “xor” operation means “exclusive OR”.

输入

The first line contains an integer T (1≤T≤5) representing the number of test cases.
For each test case, there is an integer n (1≤n≤1012) in one line.

输出

For each test case, print the answer in one line.

 

\large \sum_{i=1}^nn\%i=\sum_{i=1}^{n}\frac{n-\left \lfloor \frac{n}{i} \right \rfloor}{2^k}(mod \ 2)

 

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
bool f(ll a,ll b,ll c,ll n){
    if ( !a ){
        return ((n+1)&(b/c)&1)>0;
    }
    if ( a >= c || b >=c ){
        ll tmp = n&1 ? (n+1)/2*n : n/2*(n+1) ;
        return ((f(a%c,b%c,c,n)+(a/c)*tmp+(b/c)*(n+1))&1)>0;
    }else{
        ll m = (a*n+b)/c;
        return (((n*m)^f(c,c-b-1,a,m-1))&1)>0;
    }
}
int main()
{
    ll T,n;
    for(scanf("%lld",&T);T;T--){
        scanf("%lld",&n);
        ll ans = 0,sum=0,End=min(30000000ll,n);
        for(ll i=1;i<=End;i++){
            ans = ans ^ ( n%i );
        }
        for(ll i=End+1,j;i<=n;i=j+1){
            j = n/(n/i);
            sum = 0;
            ll Limit = (n/i)*(j-i)+n%j;
            for(ll k=1;k<=Limit;k<<=1){
                sum += f(n/i,n%j,k,j-i)*k;
            }
            ans ^=sum;
        }
        printf("%lld\n",ans);
    }
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值