学习第五天

今天上午效率挺高的,结果中午来了个亲戚,下午的效率难免低了些,不过,不会影响到我的信息学,呵呵

下面步入正题。

信息学

今天我们继续看数学相关。
lcm没有什么好讲的了,我们只要知道gcd(a,b)*lcm(a,b)==a*b就可以了。
先来看扩展gcd
这个家伙至少有两个用途,一个是求解线性不定方程,另一个是求逆元。
显然求逆元是求解线性不定方程的一种特殊形式,我们放在求逆元里单独讲。
所以先来看看求解线性不定方程。
额,找了好久,洛谷上似乎没有什么好题,反倒是盯着一个叫偶数的题看了半天,发现那是一道求逆元的题,所以,我们待会再偶数那道题。

第一道:青蛙的约会

没错,还是洛谷,但我先是在POJ上找到这道题的,然后去洛谷搜的,权且用一下洛谷吧!(等知识点复习完,我就决定弃洛谷了,用POJ或者HDU或者BZOJ或者UOJ,这个回头再说)
下面看这道题,显然是一个数学题。
首先,我们设t时刻,两个小青蛙会相遇。
那么一定有如下等式:

y+n*t=x+m*t (mod L)

这是很显然的,两者走过的路程加上初始的坐标,再对L取模,就是他们当前坐标。
那么我们下面对这个式子进行变换,得:
(n-m)*t=x-y (mod L)
所以,也就等价于:
k*L+(n-m)*t=x-y
其中k是一个未知的整数。
那么,此时,一个活生生的不定方程就出现了!
显然直接套扩展gcd就行了。
但是别忘了判断有没有解,也就是gcd(n-m,L)|(x-y)是否成立
不成立就“不可能”
还有求出t以后别忘了把它调整成最小的正整数(不定方程的整数解有无限组)
所以代码如下:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
int x,y,m,n,L;
int exgcd(int a,int b,long long& x,long long& y){
    if(b==0){
        x=1,y=0;
        return a;
    }
    int gcd=exgcd(b,a%b,y,x);
    y-=x*(a/b);
    return gcd;
}
int main(){
    scanf("%d%d%d%d%d",&x,&y,&m,&n,&L);
    int mnabs=n-m;
    int xyabs=x-y;
    long long k,t;
    int gcd0=exgcd(L,mnabs,k,t);
    if(xyabs%gcd0!=0){
        printf("Impossible");
    }else{
        long long change=xyabs/gcd0;
        t*=change; 
        long long delta=abs(L/gcd0);
        while(t>0){
            t-=delta;
        }
        while(t<0){
            t+=delta;
        }
        printf("%d",t);

    }
    return 0;
}

里面还有一些数学知识,我就不多说了,自己翻翻不定方程的数学竞赛书就行了

我们下面来看看神奇的逆元。
求逆元有很多方法,而且逆元通常作为一个题的一部分出现,很少单独出现。
但是它真的单独出现过,而且是2012年提高组的题目,下面我们就来看一看这道题。

第二题:同余方程

没错就是赤裸裸地求逆元。
其实逆元就是ax+by=c这个不定方程在c=1的时候的特殊情形。
你也许会说,我们直接套一个扩展欧几里得就行了,但是我们好不容易逮到这个题,我们就来总结一下求逆元的多种方法。

方法一:扩展欧几里得

很简单,没什么值得说的,贴代码:

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int a,b;
void exgcd(int aa,int bb,int& x,int& y){
    if(bb==0){
        x=1,y=0;
        return;
    }
    exgcd(bb,aa%bb,y,x);
    y-=x*(aa/bb);
}
int main(){
    scanf("%d%d",&a,&b);
    int xx,yy;
    exgcd(a,b,xx,yy);
    while(xx>0){
        xx-=b; 
    }
    while(xx<0){
        xx+=b;
    } 
    printf("%d",xx);
    return 0;
}

方法二:费马小定理

没错就是费马小定理
也许你知道它可以用来求取模意义下的快速幂,但正是这个快速幂的算法也可以用来求逆元。
代码如下:

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
long long a,b;
//mod为素数时,n为mod-2;mod为合数时,n为phi(mod)-1,phi为欧拉函数 
long long pow_mod(long long x,long long n,long long mod){
    long long res=1;
    while(n>0){
        if(n%2==1){
            res=res*x%mod;
        }
        x=x*x%mod;
        n/=2;
    }
    return res;
}
long long prime(long long n){
    for(long long i=2;i*i<=n;i++){
        if(n%i==0){
            return 0;
        }
    }
    return 1;
}
long long euler(long long n){
    long long res=n,aa=n;
    for(long long i=2;i*i<=n;i++){
        if(aa%i==0){
            res=res/i*(i-1);
            while(aa%i==0){
                aa/=i;
            }
        }
    }
    if(aa>1){
        res=res/aa*(aa-1);
    }
    return res;
}
int main(){
    scanf("%lld%lld",&a,&b);
    long long n;
    if(prime(b)){
        n=b-2;
    }else{
        n=euler(b)-1;
    }
    printf("%lld",pow_mod(a,n,b));
    return 0;
}

怎么使用,我在上面也写得很清楚了。
至于原理是什么,嘿嘿,没时间说了,大家自行百度。
既然提到了欧拉函数,那么我们就把欧拉函数的筛法也提一下:

void Init(){     
     euler[1]=1;    
     for(int i=2;i<Max;i++){
        euler[i]=i;
     }    
     for(int i=2;i<Max;i++){
        if(euler[i]==i){
            for(int j=i;j<Max;j+=i){
                euler[j]=euler[j]/i*(i-1);//先进行除法是为了防止中间数据的溢出 
             }       
         }    
     }    
} 

和素数的筛法一样。

方法三:线性递推

这个方法仅仅是求逆元的方法,并不是本题的方法,因为本题数据太大,显然连数组都开不下,但我还是把代码贴在这:

//O(n)递推  
const int N = 1e5 + 5;  
int inv[N];
void inverse(int n, int p) {  
    inv[1] = 1;  
    for (int i=2; i<=n; ++i) {  
        inv[i] = 1LL* (p - p / i) * inv[p%i] % p;  
    }  
}  

其实有很多这样的打表方法,都会受到数组大小的限制,所以这类方法虽然很快,但往往很少有用武之地,但还是要备着,说不定某一天,它就能在战场上救了你的命。

这么简单的题,稍微拓展一点也挺有意思的,对吧?

下面我们不看数学了,下面让我们来看看竞赛大头——动态规划!

第三题:时间不够了

如题,我们就明天再看吧!

数学

今天看了三角函数,做了些题目。
那些变换公式,还是得记得非常熟练
记?
当然不是死记硬背
我们可以多用用,这样就可以记住了。

物理

今天又做了几道题(说过了,今天下午效率较低),还是很简单
昨天忘了一样东西,就是物理解题中的一个技巧——模型转换。
那是一道点电荷放在无限大的铁板前的题,求多长时间点电荷运动到板。
它就将点电荷的运动等效为天体的运动,然后巧妙解题。
这对于我们其实有不少借鉴意义(高考就算了,这么死板的考试,不可能出现这种方法的用武之地的)

总结

今天效率很高(请自觉忽略下午),希望明天继续保持!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值