Sdoi 2010--ancient pig (lucas Algorithm & Fermat theorem & Chinese remainder Theorem)

Source: Internet
Author: User
Tags cmath

Find almost every number of topics rokua always make me tle a point ....

Figures:

The last point has been optimized for a long time finally ....

Test instructions

Ipig in the Big Fat Pig School library to check the information, learned that ancient times the total number of pig text is N. of course, a language if a lot of words, the dictionary will be very large. At that time, the king of the Pig kingdom considered that if a dictionary was repaired, the scale could be far more than the Kangxi dictionary, the cost of the pig power, the material will be difficult to measure. It is therefore considered that the exhausting of the pig was not carried out repeatedly. of course, the words of the Pig kingdom were later simplified with historical changes, and some less commonly used words were removed.

Ipig intends to study the pig text of a dynasty in ancient Times. According to the relevant literature, the pig text that was circulated in that dynasty was one of the k fractions of the ancient times, where K was a positive approximate of n (1 and n). But exactly what is one of the k, and K is how much, because the history is too long, has not been verified. Ipig think that as long as the literature, each can divide n k is possible. He intends to take into account all possible K. Obviously when K is equal to a certain value, the number of characters of the pig in this direction is N/k. however, It is also quite a lot to keep n/k from N characters. Ipig predicts that if all the possible K's cases add up to p, then the cost of studying ancient writings will be the p-th side of G.

Now he wants to know what the cost of studying ancient writings in the Pig Kingdom is. Since Ipig thinks this number can be astronomical, you just need to tell him that the answer is divided by the remainder of 999911659.

Input Format:

The input file has only one line: two numbers n, G, separated by a space.

Output format:

The output file has only one row: a number that represents the remainder of the answer divided by 999911659.

Solution

After a few days of number-theoretic exercises, I quickly saw the formula required for this topic:

ans= (gσc (k,n) (k is the factor of n))%999911659;

Can be simplified with the Fermat theorem :

ans= (gσc (k,n) (k is the factor of n)%999911658)%999911659;

because 999911658 is not a prime number, can not directly use the Lucas algorithm, so decomposition factorization 999911658=2*3*4679*35617;

Using the Lucas algorithm to merge with the Chinese remainder theorem respectively ....

The process is not much to say, the previous post has said ...

So he passed the Bzoj on the ...

The code is as follows
#include <iostream> #include <cstdio> #include <map> #include <cmath> #define LL long Long#define MoD 999911659#define mod2 999911658using namespace std;map<ll,ll> mp; LL ny[5],a[5]; LL jc[5][20010];    ll POW (ll a,ll b,ll p) {ll s=1;        While (b) {if (b&1) s=s*a%p;        b>>=1;    a=a*a%p; } return s;}    ll C (ll a,ll b,ll p) {if (b>a) return 0;    If (b*2>a) b=a-b;    LL s=1;        For (int i=1;i<=b;i++) {LL u= (a+i-b)%p;    s=s*u%p*jc[mp[p]][i]%p; } return s;}    ll Lucas (ll a,ll b,ll p) {if (b==0) return 1; return C (a%p,b%p,p) *lucas (a/p,b/p,p)%p;}    int main () {LL n,g,ans=0;    ny[1]=1;ny[2]=1;ny[3]=1353;ny[4]=31254;    a[1]=2;a[2]=3;a[3]=4679;a[4]=35617;    mp[2]=1;mp[3]=2;mp[4679]=3;mp[35617]=4;    For (int I=1;i<=4;i++) jc[i][0]=1;    For (int. i=1;i<=4;i++) {for (int j=1;j<=20000;j++) jc[i][j]=pow (j,a[i]-2,a[i]);    } scanf ("%lld%lld", &n,&g); If (g%mod==0) {priNTF ("0\n");    Return 0;                    } for (int i=1;i<=sqrt (n), i++) if (n%i==0) {if (i*i==n) for (int j=1;j<=4;j++) {                    LL S=ny[j]*lucas (n,i,a[j]);                    For (int K=1;k<=4;k++) if (k!=j) s=s*a[k]%mod2;                ans= (ans+s)%mod2;                    } else for (int j=1;j<=4;j++) {LL S=ny[j]*lucas (n,i,a[j]);                    LL S2=ny[j]*lucas (n,n/i,a[j]);                            For (int K=1;k<=4;k++) if (k!=j) {s=s*a[k]%mod2;                        s2=s2*a[k]%mod2;                } ans= (ans+s+s2)%mod2;    }} Ans=pow (g,ans,mod);    printf ("%lld\n", ans); Return 0;}

however, this will be the same as in the previous picture on the valley, will t drop a point ....

A function that finds the number of combinations is often called, and the For loop is time-consuming ...

So a little optimization (woc had a good morning ... )

As for how to optimize also see for yourself ... Now very tired ...

Front and rear contrast chart:

Code
#include <iostream> #include <cstdio> #include <map> #include <cmath> #define LL long Long#define MoD 999911659#define mod2 999911658using namespace std;map<ll,ll> mp; LL ny[5],a[5],top; LL jc[5][40010];    ll POW (ll a,ll b,ll p) {ll s=1;        While (b) {if (b&1) s=s*a%p;        b>>=1;    a=a*a%p; } return s;}    ll C (ll a,ll b,ll p) {if (a<b) return 0; return Jc[mp[p]][a]*pow (jc[mp[p]][b]*jc[mp[p]][a-b],p-2,p)%p;}    ll Lucas (ll a,ll b,ll p) {if (!b) return 1; return C (a%p,b%p,p) *lucas (a/p,b/p,p)%p;}    int main () {LL n,g,ans=0;    ny[1]=1;ny[2]=1;ny[3]=1353;ny[4]=31254;    a[1]=2;a[2]=3;a[3]=4679;a[4]=35617;    mp[2]=1;mp[3]=2;mp[4679]=3;mp[35617]=4;        For (int I=1;i<=4;i++) {jc[i][0]=1;    For (int J=1;j<=a[i];j++) jc[i][j]=jc[i][j-1]*j%a[i];    } scanf ("%lld%lld", &n,&g);    g=g%mod;        If (!g) {printf ("0\n");    Return 0;    } LL d=sqrt (n);  For (int I=1;i<=d;i++)      If (n%i==0) {if (i*i==n) for (int j=1;j<=4;j++) {LL S=ny[j]*lucas (n,i,                    a[j]);                    s=mod2/a[j]*s%mod2;                ans= (ans+s)%mod2;                    } else for (int j=1;j<=4;j++) {LL S=ny[j]*lucas (n,i,a[j]);                    LL S2=ny[j]*lucas (n,n/i,a[j]);                    s=mod2/a[j]* (s+s2)%mod2;                ans= (ans+s)%mod2;    }} Ans=pow (g,ans,mod);    printf ("%lld\n", ans); Return 0;}

This passage was made by yukino.

Sdoi 2010--ancient pig (lucas Algorithm & Fermat theorem & Chinese remainder Theorem)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.