zoukankan      html  css  js  c++  java
  • 整理一些ACM基础数学算法模板

    ACM训练整理的一些内容,,不知道放哪 就丢这吧 

    欧拉函数模板

        int r[] = new int [MAXN];
                r[1] = 1;  
                    for(int i = 2; i < MAXN; i++)  
                        r[i] = i;  
                    for(int i = 2; i < MAXN; i++)  
                        if(r[i] == i)  
                            for(int j = i; j < MAXN; j += i)  
                                r[j] = r[j] / i * (i - 1);  

    快速幂模板  x^n

    static long pow(long x,long n)
        {
            long res = 1;
            while(n>0)
            {
                if(n%2==1)
                    res = res*x%MOD;
                    x = x*x%MOD;
                    n/=2;
            }
            return res;
        }

    扩展欧几里得算法模板

    public static int extendgcd(int a,int b){  
            if(b==0){  
                x=1;  
                y=0;  
                return a;  
            }  
            int d=extendgcd(b,a%b);  
            int temp=x;  
            x=y;  
            y = temp-a/b*x;  
            return d;  
        }  

    求组合数的预处理模板 对1000000007取余

    static void PreWork()  
        {  
              for (int i=0;i<=1000;i++) 
                  C[i][0]=1;  
              for (int i=1;i<=1000;i++)  
                 for (int j=1;j<=1000;j++)  
                   C[i][j]=(C[i-1][j]+C[i-1][j-1])%INF;  
        
        }  

    中国剩余定理 普通版本模板   HDU 1573  参考:http://blog.csdn.net/a601025382s/article/details/10296577

        for(int i = 0;i<m;i++)
                    a[i] = in.nextInt();       // 除数,不一定互质
                for(int i = 0;i<m;i++)
                    b[i] = in.nextInt();      //余数  
                    int m1 = a[0],r1 = b[0],m2,r2;
                    int flag = 0;
                 for(int i=1;i<m;i++)  
                    {  
                        m2=a[i];
                        r2=b[i];  
                        int c=r2-r1; 
                        int d = extendgcd(m1,m2);//d=gcd(m1,m2);x*m1+y*m2=d;  
                        if(c%d!=0) 
                        {  
                            flag =1;
                            break;
                        }  
                        int t=m2/d;
                        x=(c/d*x%t+t)%t;
                        r1=m1*x+r1;
                        m1=m1*m2/d;  
                    }

        r1 为最小整数解 m1*i+r1 (i = 0,1,2.....)  都是满足条件的解

    除法取模  (费马小定理)

    求 a / b = x (mod M)

    只要 M 是一个素数,而且 b 不是 M 的倍数,就可以用一个逆元整数 b’,通过 a / b = a * b' (mod M),来以乘换除。

    费马小定理说,对于素数 M 任意不是 M 的倍数的 b,都有:

    b ^ (M-1) = 1 (mod M)
    

    于是可以拆成:

    b * b ^ (M-2) = 1 (mod M)
    

    于是:

    a / b = a / b * (b * b ^ (M-2)) = a * (b ^ (M-2)) (mod M)
    

    也就是说我们要求的逆元就是 b ^ (M-2) (mod M)

    求解fibonacci数列 矩阵快速幂 对10000取模

    import java.util.Scanner;
    
    
    public class Main {
    			private static final int MOD = 10000;
    			private static Node base;
    			private static Node ans;
    	public static void main(String[] args) {
    		base = new Node();
    		ans = new Node();
    		base.m = new int [2][2];
    		ans.m = new int [2][2];
    
    		Scanner in = new Scanner (System.in);
    		while(in.hasNext())
    		{
    			int n = in.nextInt();
    			if(n==-1)
    				break;
    			System.out.println(fast_mod(n));
    		}
    
    	}
    
    	static int fast_mod(int n)  // 求矩阵 base 的  n 次幂 
    	{
    	    base.m[0][0] = base.m[0][1] = base.m[1][0] = 1;
    	    base.m[1][1] = 0;
    	    ans.m[0][0] = ans.m[1][1] = 1;  // ans 初始化为单位矩阵 
    	    ans.m[0][1] = ans.m[1][0] = 0;
    	    while(n!=0)
    	    {
    	        if(n % 2 == 1)  //实现 ans *= t; 其中要先把 ans赋值给 tmp,然后用 ans = tmp * t 
    	            ans = multi(ans, base);
    	        
    	        base = multi(base, base);
    	        n >>= 1;
    	    }
    	    return ans.m[0][1];
    	}
    
    	
    	static Node multi(Node a, Node b)//定义矩阵乘法
    	{
    	    Node tmp = new Node();
    	    tmp.m = new int [2][2];
    	    for(int i = 0; i < 2; ++i)
    	    {
    	        for(int j = 0; j < 2; ++j)
    	        {
    	            tmp.m[i][j] = 0;
    	            for(int k = 0; k < 2; ++k)
    	                tmp.m[i][j] = (tmp.m[i][j] + a.m[i][k] * b.m[k][j]) % MOD;
    	        }
    	    }
    	    return tmp;
    	}
    	
    	static class Node{
    		  int m[][];
    	}
    }
    

      

     斯特林数   (划分集合的方法数)

    static void init()
    	{
    	   
    	    s[1][1]=1;
    	    for(int i=2; i<=1000; i++)
    	    {
    	        for(int j=1; j<=i; j++)
    	        {
    	            s[i][j]=(s[i-1][j-1]+j*s[i-1][j])%INF;
    	        }
    	    }
    	}
    

      

         待补充。。。

  • 相关阅读:
    1111实验二 作业调度模拟实验
    1006实验一实验报告
    0909对操作系统的认识
    南阳OJ-138 找球号(二)(hash表应用)
    南阳OJ-38 布线问题(最小生成树应用_prim)
    插入排序
    南阳OJ-756 重建二叉树(二叉树的中序遍历和后序遍历求先序遍历)
    南阳OJ-63 小猴子下落(数据结构-二叉树)
    UVA OJ-11095 Maximum Product(暴力求解法)
    UVA OJ-725 Division (暴力求解法)
  • 原文地址:https://www.cnblogs.com/pcry/p/5695085.html
Copyright © 2011-2022 走看看