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;
	        }
	    }
	}

  

 

 

     待补充。。。