大数模运算(POJ 1845)

http://blog.sina.com.cn/s/blog_6635898a0100omcn.html

直接抄过来了(不好意思)

题意:求A^B的所有约数之和 Mod 9901。

 

思路:大数模运算。两个最基本公式:(A*B)%C = ((A%C)*(B%C))%C 和 (A+B)%C = ((A%C)+(B%C))%C 。用__int64的原因为 n = cnt[i] * B (cnt[i]为A第i个素因子的个数)可能会超int。

 

1: 对A进行素因子分解得

     A = p1^a1 * p2^a2 * p3^a3 *...* pn^an.
  故 A^B = p1^(a1*B) * p2^(a2*B) *...* pn^(an*B);


2:A^B的所有约数之和为:

     sum = [1+p1+p1^2+...+p1^(a1*B)] * [1+p2+p2^2+...+p2^(a2*B)] *...* [1+pn+pn^2+...+pn^(an*B)].

  如 200 = 2^3 * 5^2 :  sum(200) = [1 + 2 + 4 + 8] * [1 + 5 + 25].


3: 求等比数列1+pi+pi^2+pi^3+...+pi^n可以由递归形式的二分求得:(模运算不能用等比数列和公式!(乘法逆元)
   若n为奇数,一共有偶数项,则:
      1 + p + p^2 + p^3 +...+ p^n

      = (1+p^(n/2+1)) + p * (1+p^(n/2+1)) +...+ p^(n/2) * (1+p^(n/2+1))
      = (1 + p + p^2 +...+ p^(n/2)) * (1 + p^(n/2+1))

   如:1 + p + p^2 + p^3 + p^4 + p^5 = (1 + p + p^2) * (1 + p^3)
   若n为偶数,一共有奇数项,则:
      1 + p + p^2 + p^3 +...+ p^n

      = (1+p^(n/2+1)) + p * (1+p^(n/2+1)) +...+ p^(n/2-1) * (1+p^(n/2+1)) + p^(n/2)
      = (1 + p + p^2 +...+ p^(n/2-1)) * (1+p^(n/2+1)) + p^(n/2);

   如:1 + p + p^2 + p^3 + p^4 = (1 + p) * (1 + p^3) + p^2

 

 

import java.io.*;
import java.util.*;
import java.math.*;

public classMain {
	
	static final int MOD = 9901;
	int a[], b[], len, A;
	long B;
	
	long Pow(long p, long n) {
		long res = 1;
		while (n > 0) {
			if ((n & 1) > 0) res = (res * p) % MOD;
			n >>= 1;
			p = (p * p) % MOD;
		}
		return res;
	}
	
	long Sum(long p, long n) {
		if (n == 0) return 1;
		if ((n & 1) > 0) 
			return ((1 + Pow(p, n / 2 + 1)) * Sum(p, n / 2)) % MOD;
		else 
			return ((1 + Pow(p, n / 2 + 1)) * Sum(p, n / 2 - 1) + Pow(p, n / 2)) % MOD;
	}
	
	void run() {
		A = cin.nextInt();
		B = cin.nextInt();
		int n = (int) Math.sqrt(A), tn = A;
		a = new int[n + 1];
		b = new int[n + 1];
		len = 0;
		for (int i = 2; i <= n && i <= tn; i++) {
			if (tn % i == 0) {
				a[len] = i;
				while (tn % i == 0) {
					tn /= i;
					b[len]++;
				}
				len++;
			}
		}
		if (tn > 1) {
			a[len] = tn;
			b[len++] = 1;
		}
		long ans = 1;
		for (int i = 0; i < len; i++) 
			ans = (ans * Sum(a[i], b[i] * B)) % MOD;
		System.out.println(ans);
	}               
	
	public static void main(String[] args) {
		Mainsolved = new Main();
		solved.run();
	}
	
//	static InputStream inputStream = System.in;
//	static InputReader cin = new InputReader(inputStream);
	
	Scannercin = new Scanner(new BufferedInputStream(System.in));
	
}


classInputReader { 

    private InputStreamstream; 
    private byte[] buf = new byte[1024]; 
    private int curChar; 
    private int numChars; 

    public InputReader(InputStreamstream) { 
        this.stream = stream; 
    } 

    public int read() { 
        if (numChars == -1) 
            return -1; 
            //throw new InputMismatchException(); 
        if (curChar >= numChars) { 
            curChar = 0; 
            try { 
                numChars = stream.read(buf); 
            } catch (IOExceptione) { 
                throw new InputMismatchException(); 
            } 
            if (numChars <= 0) 
                return -1; 
        } 
        return buf[curChar++]; 
    } 

    public int nextInt() { 
        int c = read(); 
        if (c == -1) 
            return -1; 
        while (isSpaceChar(c)) 
            c = read(); 
        int sgn = 1; 
        if (c == '-') { 
            sgn = -1; 
            c = read(); 
        } 
        int res = 0; 
        do { 
            if (c < '0' || c > '9') 
                throw new InputMismatchException(); 
            res *= 10; 
            res += c - '0'; 
            c = read(); 
        } while (!isSpaceChar(c)); 
        return res * sgn; 
    } 
     
    public Stringnext() {   
        StringBuilderstr = new StringBuilder();   
        int ch;   
        while (isSpaceChar(ch = read()));   
        if (ch == -1)   
            return null;   
        do {   
            str.appendCodePoint(ch);   
        } while (!isSpaceChar(ch = read()));   
        return str.toString();   
    }  
     
    public static boolean isSpaceChar(int c) { 
        return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1; 
    } 

    public char nextCharacter() { 
        int c = read(); 
        while (isSpaceChar(c)) 
            c = read(); 
        return (char) c; 
    } 

} 

 

 

posted on 2013-02-20 20:28  Sure_Yi  阅读(510)  评论(0编辑  收藏  举报

导航