"SDOI2010" ancient pig culture Lucas + Chinese remainder theorem

Meaning of the questions:

Long history of civilization pig Kingdom, profound.

iPig access to information in the school library in a large pig, that in ancient times the total number of pig body text is N. Of course, if a language many words, the dictionary will be correspondingly large. At that time the king of the Kingdom of pigs taking into account if repair a dictionary, there may far exceed the size of Kangxi, pigs spent force, material will be incalculable. So consider this one again and again no workers cite the pig waste of money. Of course, the word pig Kingdom and later with the historical changes gradually simplified, removing some of the less frequently used words.

iPig intends to study the ancient dynasties of a pig body text. According to the relevant literature, the dynasty spread pig body text exactly one sub ancient times k, where k is a positive divisor of N (which may be 1 and N). But what is one of the specific points k, and k is the number, because the history is too long, it has been difficult to trace.

Document iPig that they meet, each N is divisible by k are possible. He intends to take into account all the possible k. Obviously when k is equal to a predetermined value, the number of pigs towards the body text of \ (\ FRAC {N}} {k \) . However, from the N character in the reserve \ (\ frac {N} {
k} \) th situation is considerably more. iPig is expected, if the number of cases all add up all the possible k is P, then he studied the ancient texts of the cost will be the power of P G's.

Now he wants to know the cost of the ancient kingdom of porcine character is. Since the iPig feel that this figure may be astronomical, so you only need to tell him the answer is divided by 999,911,659 on it.

Input:

Ancient.in input file and only one line: two numbers N, G, separated by a space.

Output:

Output file ancient.out has one and only one line: a number that represents the answer to the remainder of the division 999 911 659.

Ideas:

(Indicate when the examination is not complete)
1, the first \ (P \) be large, it is necessary to have a modulus \ (X \) satisfies \ (G ^ {P mod x } \ equiv G ^ P (mod \, Mod) \)

The Fermat's little theorem \ (G ^ {Mod-1 } \ equiv1 (mod \, Mod) \) seen \ (X =-Mod. 1 \) .
As may be \ (P \) is split into \ (\ frac {P} { x} \) a \ (X \) is multiplied by multiplying by \ (P% X \) , for the number in front of \ (Mod \ ) in the case of modulo are \ (1 \) , will not affect the answer

2, calculation is required in the subject \ (G ^ {\ sum_ { x | n} C_ {n} ^ {x}} \) so we need to deal out the number of combinations.

However, the title of \ (n-\) range up to \ (1000000000 \) , and an inverse element with recursive computation are not directly, but can be found in \ (Mod-1 \) can be split into four product of prime numbers, i.e., \ (= 2 * 3 * 999 911 658 4679 35 617 * \) where only the largest \ (35617 \) , then you can choose to use \ (Lucas \) Now science is not proven

That is like this:

int lucas(int x,int y,int p) {
    if(y==0)return 1;
    return 1ll*calc(x%a[p],y%a[p],p)*lucas(x/a[p],y/a[p],p)%a[p];
}

(The above refers to p modulo four)

3. For each module we have obtained a number of combinations, then the problem is converted to find a number that

For \ (i∈ [1,4] \) is satisfied, \ (X \ equiv B_i (MOD \, a_i) \)

This formula also can use Chinese Remainder Theorem solving √

Some knowledge of the above mentioned points should be quite important, although I will not be a test when a stranger

Note: If the \ (G = Mod \) answer should be \ (0 \) , but according to Lucas solving will come \ (1 \) , special sentence about

Well if the time card, you can choose to push inverse linear.

code show as below:

#include<bits/stdc++.h>
#define Mod 999911659
using namespace std;
int n,G,a[]= {2,3,4679,35617},b[4],pr[4][35620],ni[4][35620];
int mul(int x,int y,int mod) {
    int res=1;
    while(y) {
        if(y&1)res=1ll*res*x%mod;
        x=1ll*x*x%mod,y>>=1;
    }
    return res;
}
int calc(int x,int y,int p) {
    return 1ll*pr[p][x]*ni[p][y]%a[p]*ni[p][x-y]%a[p];
}
int lucas(int x,int y,int p) {
    if(y==0)return 1;
    return 1ll*calc(x%a[p],y%a[p],p)*lucas(x/a[p],y/a[p],p)%a[p];
}
int ans=0;
void exgcd(int A,int B,int &x,int &y) {
    if(B==0)x=1,y=0;
    else exgcd(B,A%B,y,x),y-=(A/B)*x;
}
void Calc(int x,int y) {
    int M=1;
    for(int i=0; i<4; i++)b[i]=lucas(x,y,i),M*=a[i];
    int tot=0;
    for(int i=0; i<4; i++) {
        int A=0,B=0,p=M/a[i];
        exgcd(p,a[i],A,B);//(A*p)%a[i]=1
        A=(A%a[i]+a[i])%a[i];
        tot=(tot+1ll*A*b[i]%M*p%M)%M;
    }
    ans=(ans+tot)%(Mod-1);
}
int main() {
    scanf("%d%d",&n,&G);
    int k=sqrt(n);
    for(int i=0; i<4; i++) {
        pr[i][0]=1,ni[i][0]=1;
        for(int j=1; j<=a[i]; j++)pr[i][j]=1ll*pr[i][j-1]*j%a[i],ni[i][j]=mul(pr[i][j],a[i]-2,a[i]);
    }
    if(Mod==G)printf("0\n");
    else {
        for(int i=1; i<=k; i++) {
            if(n%i)continue;
            int a=i,b=n/i;//c(n,a)+c(n,b)
            Calc(n,a);
            if(a!=b)Calc(n,b);
        }
        printf("%d\n",mul(G,ans,Mod));
    }
    return 0;
}

Guess you like

Origin www.cnblogs.com/cly1231/p/11355743.html