寒训day9 初等数论

初等数论四大定理

威尔逊定理

( ( p − 1 ) ! + 1 ) % p = 0 ((p-1)!+1) \% p = 0 ((p1)!+1)%p=0
其中,p是质数。

HDU 2973

HDU  2973

题意

多组数据,给n,求 S n S_n Sn

分析

化简成 ( ( p − 1 ) ! + 1 ) / p ((p-1)!+1) / p ((p1)!+1)/p的形式,可以发现若 3 k + 7 3k+7 3k+7是质数,整块为1,否则为0。

代码

暴力了一波,果然TLE。最后稍微记忆化就过了。Leaderboard上面有打素数表的,时间减半。

#include<cstdio>
#include<cmath>
using namespace std;
int ans[1000006];
is_prime(int x)
{
    if(x==1)return false;
    int sq=sqrt(x);
    for(int i=2;i<=sq;i++)
    if(x%i==0)
    {
        return false;
    }
    return true;
}
int main()
{
    int t,n,cnt=1;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        if(n>=cnt)
            for(;cnt<=n;cnt++)
                ans[cnt]=ans[cnt-1]+is_prime(3*cnt+7);
        printf("%d\n",ans[n]);
    }
}

欧拉定理

a φ ( n ) ≡ 1   ( m o d   n ) a^{φ (n)}≡1\ (mod\ n) aφ(n)1 (mod n)
其中 φ ( n ) φ (n) φ(n)是欧拉函数,表示小于n的正整数中与n互质的数的数目。

中国剩余定理(孙子定理)

费马小定理

a p − 1 ≡ 1 ( m o d p ) a^{p-1}≡1\pmod{p} ap11(modp)
其中,p是质数。其实就是欧拉定理的特例。

求除法取模逆元

a b = a ∗ b p − 2 ( m o d p ) \frac{a}{b}=a*b^{p-2}\pmod{p} ba=abp2(modp)
证明 设 { a b = k 1 ∗ p + y 1 a ∗ x = k 2 ∗ p + y 2 a b − a ∗ x = k ∗ p + y 且 x ∗ b = 1 ( m o d p ) ∵ a − a ∗ x ∗ b = k ∗ p ∗ b + y ∗ b ( a − a ∗ x ∗ b ) = ( k ∗ p ∗ b + y ∗ b ) ( m o d p ) 0 = y ∗ b 又 ∵ b = ̸ 1 ∴ y = 0 又 ∵ x ∗ b = 1 , b p − 1 ≡ 1 ( m o d p ) ∴ x = b p − 2 可 使 a b = a ∗ x ( m o d p ) 成 立 . 设\begin{cases}\frac{a}{b}=k1*p+y1\\a*x=k2*p+y2\\\frac{a}{b}-a*x=k*p+y\end{cases}且x*b=1\pmod{p}\\ \because a-a*x*b=k*p*b+y*b\\(a-a*x*b)=(k*p*b+y*b)\pmod{p}\\ 0=y*b又\because b=\not1\\ \therefore y=0又\because x*b=1, b^{p-1}≡1\pmod{p}\\ \therefore x=b^{p-2}可使\frac{a}{b}=a*x\pmod p成立. ba=k1p+y1ax=k2p+y2baax=kp+yxb=1(modp)aaxb=kpb+yb(aaxb)=(kpb+yb)(modp)0=ybb≠1y=0xb=1,bp11(modp)x=bp2使ba=ax(modp).
丑陋证毕.

玄学判素数

伪素数

扩展

扩展欧几里得算法

反素数

定义:约数个数比所有小于x的正整数多,则称x为反素数。

约数数量与质因数的关系

约数数量 n = 1 ∗ ( t 1 + 1 ) ∗ ( t 2 + 1 ) ∗ ( t 3 + 1 ) . . . n=1*(t1+1)*(t2+1)*(t3+1)... n=1(t1+1)(t2+1)(t3+1)...其中 t 1 , t 2... t1,t2... t1,t2...为各个质因数的数量。

反素数的质因数规律

反素数的所有质因子必然是从2开始的连续若干个质数,且 x = 2 t 1 ∗ 3 t 2 ∗ 5 t 3 . . . ( t 1 ≥ r 2 ≥ t 3... ) x=2^{t1}*3^{t2}*5^{t3}...(t1≥r2≥t3...) x=2t13t25t3...(t1r2t3...),因为反素数是保证约数个数为 n n n的这个数 x x x尽量小,用反证法易证。

#include<cstdio>
#include<algorithm>
#define un unsigned int
using namespace std;
un per[10]={2,3,5,7,11,13,17,19,23,29},maxY=0,ans=2e9,n;
void dfs(un Y,char dep,un num,char last)
{
	if(Y>maxY)maxY=Y,ans=num;
	if(Y==maxY)ans=min(ans,num);
	for(char i=1;num<=n/per[dep]&&i<=last;i++)
		dfs(Y*(i+1),dep+1,num*=per[dep],i);
}
int  main()
{
	char t;
	scanf("%d",&t);
	for(char i=1;i<=t;i++)
	{
		maxY=0,ans=2e9;
		scanf("%u",&n);
		dfs(1,0,1,33);
		printf("Case #%d: %u\n",i,ans);
	}
}

当然,反素数是十分稀有的。换而言之,打表出奇迹。

#include<cstdio>
#include<algorithm>
#define un unsigned int
using namespace std;
un a[]={1396755360,1102701600,735134400,698377680,551350800,367567200,294053760,245044800,183783600,147026880,122522400,110270160,73513440,61261200,43243200,36756720,32432400,21621600,17297280,14414400,10810800,8648640,7207200,6486480,4324320,3603600,2882880,2162160,1441440,1081080,720720,665280,554400,498960,332640,277200,221760,166320,110880,83160,55440,50400,45360,27720,25200,20160,15120,10080,7560,5040,2520,1680,1260,840,720,360,240,180,120,60,48,36,24,12,6,4,2,1};
int  main()
{
	un t,n;
	scanf("%u",&t);
	for(un i=1;i<=t;i++)
	{
		scanf("%u",&n);
		un j;
		for(j=0;a[j]>n;j++);
		printf("Case #%u: %u\n",i,a[j]);
	}
}

Locas定理

n = a p + b , m = c p + d n=ap+b,m=cp+d n=ap+b,m=cp+d,( p p p is a prime number)
( n m ) = ( a c ) ∗ ( b d )   ( m o d   p ) {n\choose m}={a\choose c}*{b\choose d}\ (mod\ p) (mn)=(ca)(db) (mod p)

非严谨证明

二项式定理+费马小定理
由 ( 1 + x ) p = 1 + x = 1 + x p   ( m o d   p ) 得 由(1+x)^p=1+x=1+x^p\ (mod\ p)得 (1+x)p=1+x=1+xp (mod p)

( 1 + x ) n = ( 1 + x ) a p ( 1 + x ) b = ( 1 + x p ) a ( 1 + x ) b   ( m o d   p ) (1+x)^n=(1+x)^{ap}(1+x)^b=(1+x^p)^{a}(1+x)^b\ (mod\ p) 1+xn=(1+x)ap(1+x)b=(1+xp)a(1+x)b (mod p)
则其中 x m x^m xm的系数就是 ( n m ) = ( a c ) ∗ ( b d )   ( m o d   p ) {n\choose m}={a\choose c}*{b\choose d}\ (mod\ p) (mn)=(ca)(db) (mod p)

费马大定理

当整数 n &gt; 2 n&gt;2 n>2时,关于 x , y , z x,y,z x,y,z的不定方程
x n + y n = z n x^n+y^n=z^n xn+yn=zn没有正整数解。

Berlekamp–Massey算法

C++11的代码

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define rep(i,a,n) for (int i=a;i<n;i++)
#define per(i,a,n) for (int i=n-1;i>=a;i--)
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define SZ(x) ((ll)(x).size())
typedef vector<ll> VI;
typedef pair<ll,ll> PII;
const ll mod = 1000000007;
ll powmod(ll a,ll b) {
	ll res=1;
	a%=mod;
	assert(b>=0);
	for(;b;b>>=1){
	if(b&1) res=res*a%mod;
	a=a*a%mod;
	}
	return res;
}
ll _,n;
namespace linear_seq {
    const int N=10010;
    ll res[N],base[N],_c[N],_md[N];
    vector<ll> Md;
    void mul(ll *a,ll *b,ll k) {
        rep(i,0,k+k) _c[i]=0;
        rep(i,0,k)
		if (a[i])
		rep(j,0,k)
		_c[i+j]=(_c[i+j]+a[i]*b[j])%mod;
        for (ll i=k+k-1;i>=k;i--)
		if (_c[i])
            rep(j,0,SZ(Md))
			_c[i-k+Md[j]]=(_c[i-k+Md[j]]-_c[i]*_md[Md[j]])%mod;
        rep(i,0,k) a[i]=_c[i];
		}
    ll solve(ll n,VI a,VI b) {
    	ll ans=0,pnt=0;
    	ll k=SZ(a);
        assert(SZ(a)==SZ(b));
        rep(i,0,k) _md[k-1-i]=-a[i];_md[k]=1;
        Md.clear();
        rep(i,0,k) if (_md[i]!=0) Md.push_back(i);
        rep(i,0,k) res[i]=base[i]=0;
        res[0]=1;
        while ((1ll<<pnt)<=n) pnt++;
        for (ll p=pnt;p>=0;p--) {
            mul(res,res,k);
            if ((n>>p)&1) {
                for (ll i=k-1;i>=0;i--) res[i+1]=res[i];res[0]=0;
                rep(j,0,SZ(Md))
				res[Md[j]]=(res[Md[j]]-res[k]*_md[Md[j]])%mod;
            }
        }
        rep(i,0,k) ans=(ans+res[i]*b[i])%mod;
        if(ans<0) ans+=mod;
        return ans;
    }
    VI BM(VI s) {
        VI C(1,1),B(1,1);
        ll L=0,m=1,b=1;
        rep(n,0,SZ(s)) {
            ll d=0;
            rep(i,0,L+1) d=(d+(ll)C[i]*s[n-i])%mod;
            if (d==0) ++m;
            else if (2*L<=n) {
                VI T=C;
                ll c=mod-d*powmod(b,mod-2)%mod;
                while (SZ(C)<SZ(B)+m) C.pb(0);
                rep(i,0,SZ(B)) C[i+m]=(C[i+m]+c*B[i])%mod;
                L=n+1-L; B=T; b=d; m=1;
            }
			else {
                ll c=mod-d*powmod(b,mod-2)%mod;
                while (SZ(C)<SZ(B)+m) C.pb(0);
                rep(i,0,SZ(B)) C[i+m]=(C[i+m]+c*B[i])%mod;
                ++m;
            }
        }
        return C;
    }
    ll gao(VI a,ll n) {
        VI c=BM(a);
        c.erase(c.begin());
        rep(i,0,SZ(c)) c[i]=(mod-c[i])%mod;
        return solve(n,c,VI(a.begin(),a.begin()+SZ(c)));
    }
};

int main() {
	while(~scanf("%lld",&n)){
		printf(" %lld\n",linear_seq::gao(VI{1,1,2,3,5},n-1));
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值