zoukankan      html  css  js  c++  java
  • [专题总结]数学综合

    前言

        这里记录一些较琐碎的数学知识。
    

    BSGS

    博文:yyb的BSGS算法
    设要求解的方程是(a^{x}equiv c(mod;p)),设(p=tm-b),注意:

    • 一开始就要判断一下c是否为1,即解是否为0,然后枚举t的范围是((0,m+1])t一定不能枚举0,因为这样子(p=tm-b)可能会为负数。
    • 一个看上去不足道的细节:当(a=0)时不能使用BSGS算法求解。但这个细节的意义却值得注意。我们推式子时习惯于(a=b Leftrightarrow ca=cb (c eq 0)),却常常忽略了((c eq 0)),这个条件。类似的例子还有等比数列求和公式,当然那个例子更引人注目的是((a eq 1))

    [SDOI2013]随机数生成器WA了N发的我痛定思痛

    exBSGS

    注意除d的时候要判断x是否可以取0。

    群论

    其实OI中用到的只是置换群以及那两个定理吧?
    知识点是在《组合数学》上学的,因为可以勾勾画画,所以就不搬上来了(qwq)
    幸好是在《组合数学》上学的,不然看各种说法不一的题解很容易迷茫的。
    那就说几道题。

    [POI2009]SLO

    置换+贪心,这种模型好像是第二次见了,值得注意。

    [HNOI2008]Cards

    友好的burnside定理入门题。注意要加入单位元才能构成置换群,简单DP与burnside结合计数似乎是常见套路。

    一个关于n阶循环群的结论

    设n阶循环群(G=left {p_{0},p_{1},...,p_{n-1} ight }),则(p_{i})的循环个数为(gcd(i,n))

    [SHOI2006]有色图

    刚开始颓题解时觉得好难。其实核心思想就是把计算点置换(f)的不动点数(c(f))转化为计算边置换(g)的不动点数(c(g)),其它的都好推。

    [Hnoi2010]物品调度

    挺好的题。就是总感觉不相信这样做是对的。

    Miller_rabin&Pollard_rho

    [P4718]【模板】Pollard-Rho算法

    这是真duliu题。
    做完这题我才知道我写的Pollard_rho有多假。
    天真的我直接上慢速乘,T飞,必须用__int128或long double才能过,但是我的代码用long double还过不了。。。
    代码和注释可以看一下。

    #include<bits/stdc++.h>
    #define rg register
    using namespace std;
    typedef long long LL;
    const int mod=1e9+7;
    LL read(){
    	LL x=0,w=0;char ch=0;
    	while(!isdigit(ch)) w|=ch=='-',ch=getchar();
    	while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
    	return w?-x:x;
    }
    int X,A,B;
    inline void init(){
    	srand(time(0));
    	X=rand(),A=rand()+1,B=rand()+1;
    }
    inline int rd(){return X=(1ll*X*A+B)%mod;}    //自己写rand()可以取到范围更大的随机值,而且会快一点(然而我写的这个好像很不随机)
    inline LL mul(LL a,LL b,LL p){return (__int128)a*b%p;}
    //inline LL mul(LL a,LL b,LL p){return (a*b-(LL)((long double)a*b/p+1e-9)*p)%p;} 这个过不了 
    inline LL kpow(LL a,LL k,LL p){
    	LL res=1;
    	for(;k;k>>=1,a=mul(a,a,p))if(k&1)res=mul(res,a,p);
    	return res;
    }
    inline LL gcd(LL a,LL b){	//比较sao的gcd写法 
        while(b^=a^=b^=a%=b);  
        return a;  
    }  
    bool test(LL p,LL a){
    	LL d=p-1;rg int s=0;
    	for(;!(d&1);d>>=1,++s) ;
    	a=kpow(a,d,p);
    	while(s--){
    		LL b=mul(a,a,p);
    		if(b==1&&(a!=1&&a!=p-1)) return false;
    		a=b;
    	}
    	return a==1;
    }
    bool miller_rabin(LL p){	//没错,miller_rabin的终极境界就是:疯狂特判,能判就判,循环展开,面向数据(实测素数只取2和61就能过) 
    	if(p==46856248255981ll||p<2) return false;
        if(p==2||p==3||p==7||p==61||p==24251) return true;
        return test(p,2)&&test(p,61);
    }
    LL pho(LL x){
    	LL s=rd(),t=s,c=rd()+1;
    	LL val=1,d;
    	for(rg int i=1;;i<<=1,s=t,val=1){	//题解里看到的优化,就是累乘127次再求gcd,这个闸值可以自己调
    		for(rg int j=1;j<=i;++j){
    			t=(mul(t,t,x)+c)%x;
    			val=mul(val,abs(t-s),x);
    			if(j%127==0&&(d=gcd(val,x))>1) return d;
    		}
    		if((d=gcd(val,x))>1) return d;
    	}
    }
    LL mx;
    void divide(LL x){
    	if(x<=mx||x<2) return ;	//x<2一定要写啊,不然T飞 
    	if(miller_rabin(x)){mx=max(mx,x);return;}
    	LL d=x;
    	while(d==x) d=pho(x);	//不知道为什么pollard_rho似乎经常返回x本身 
    	while(x%d==0) x/=d;
    	divide(x),divide(d);
    }
    int main(){
    	init();
    	int cas=read();
    	while(cas--){
    		mx=0;LL x=read();
    		if(x==1) puts("1");
    		else{
    			divide(x);
    			if(mx==x) puts("Prime");
    			else printf("%lld
    ",mx);
    		}
    	}
    	return 0;
    }
    

    博弈论

    k-Nim游戏

    (n)堆石子(a_{1},...a_{n}),一次操作可以从(1 sim k)堆石子中取任意数量的石子,不能取者败。
    拿来主义:
    结论是,设(c_{i}=sum_{j}[(a_{j}>>i)&1]),则先手必败的充要条件是(forall c_{i}\%(k+1)=0),否则先手必胜。

    [SDOI2011]黑白棋

    转化为确定从左往右每对黑白棋之间的距离,共(k/2)对,相当于(k/2)堆石子。考虑求不合法方案数,设(f[i][j])表示使得(j)石子的(c_{0} sim c_{i-1}\%(k+1))都为0的方案数,转移枚举(c_{i})的大小(必须能整除(k+1)),然后分给(k/2)堆石子。
    设最高位为14。则(f[15][i])的贡献为(C(n-i-k/2,k/2)),这里的证明挺有趣的,但懒得写了。

    SG游戏&Nim游戏

    博弈论好难啊啊啊。
    学习资料
    https://blog.csdn.net/A_Comme_Amour/article/details/79347291
    集训队论文《组合游戏略述——浅谈SG游戏的若干拓展及变形》

    [SP2021]PEBBMOV-Moving Pebbles

    我认为很难想的一道题。先找出必败态以及后手模仿先手的思路都挺不错的。

    数论函数&莫反

    [BZOJ4173]数论

    这是神仙题。巧妙地运用了式子

    [left lfloor frac{n+m}{k} ight floor-left lfloor frac{n}{k} ight floor-left lfloor frac{m}{k} ight floor ]

    的值只能等于(0)(1)的性质以及等式

    [sum_{i=1}^{n}i=sum_{i=1}^{n}sum_{d|i}phi(d)=sum_{i=1}^{n}phi(i)left lfloor frac{n}{i} ight floor ]

    原根

    定义、性质、定理都挺多的。我也就记了几个结论,不知道这东西真要考的话会怎么考。
    知识点推荐OI Wiki-原根
    Upd:知道怎么考了,就是在模质数p意义下可以把1~p-1唯一对应成p的原根的幂,这样相乘就变成了指数相加,实现乘法转加法。

    二项式反演

    二项式反演及其应用

    线性基

    实际上就是维护一个上三角矩阵。
    线性基学习笔记

  • 相关阅读:
    近期计划安排
    线段树+离散化+染色
    矩阵快速幂(共轭函数两种递推式)
    树状数组求区间最值和单点更新
    矩阵快速幂(共轭函数)
    树状数组之区间更新与查询
    Python List min()方法
    Python List max()方法
    Python List len()方法
    Python List cmp()方法
  • 原文地址:https://www.cnblogs.com/gosick/p/12189543.html
Copyright © 2011-2022 走看看