BZOJ-2186 (Number Theory)

topic

2186: [Sdoi2008] The Confusion of Princess Salad
Time Limit: 10 Sec Memory Limit: 259 MB

Description

Due to inflation and the proliferation of counterfeit banknotes, the government decided to introduce a new policy: The existing banknote numbers range from 1 to N factorial, but the government only issues banknotes with a number that is mutually prime. Princess Salad, the largest real estate owner, decided to predict the current number of real money in the Monopoly nation. Now, please help Princess Sara to solve this problem. Since the number of sheets may be very large, you only need to calculate the answer after taking the modulo R. R is a prime number.

Input

The first line is two integers T and R. R<=10^9+10, T<=10000, indicating the number of test data in the group, R is the modulus.
The next T line, each line is a pair of integers N, M, see the title description m<=n
For 100% data, 1 <= N, M <= 10000000

Output

A total of T lines, for each pair of N, M, output 1 to N! China and M! The value of the number of qualities modulo R

Sample Input

5 1000000007

35434 3244
10000000 1324
2316354 3243354
24223 242
1534234 123432

Sample Output

330733849
347925786
796298408
445433358
152561042

analysis

  • The question is to ask how many numbers 1~(n!) are relatively prime to m!, and the answer is modulo R.
  • I really don't know this question. I didn't understand it until I read this blog post. Let's put it here.
  • (http://blog.csdn.net/PoPoQQQ/article/details/39957117)

program

#include <cstdio>
#define N 10000002
typedef int ll;
ll i,j,T,k,Ha,n,m,ans,p[665000],v[N],g[N],h[N],num;
long long ret;
bool f[N];
//v:i的逆元    g:i的阶乘     h:Pi((p[i]-1)/p[i],a[i]<=i)

ll ksm(ll x,ll y){
    for (ret=1; y; y>>=1,x=((long long)x*x)%Ha)
        if (y&1) ret=(long long)ret*x%Ha;
    return ret;
}

void get_p(){
    for (g[1]=h[1]=v[1]=1,i=2; i<N; i++){  
        g[i]=(long long)g[i-1]*i%Ha;
        v[i]=(long long)v[Ha%i]*(Ha-(Ha/i))%Ha;
        if (!f[i]){
            p[++num]=i;
            h[i]=(long long)h[i-1]*(i-1)%Ha*v[p[num]%Ha]%Ha;
        }else h[i]=h[i-1];
        for (j=1; j<=num && (long long)i*p[j]<N; j++){
            f[i*p[j]]=1;
            if(i%p[j]==0) break;
        }
    }
}

int main(){
    scanf("%d%d",&T,&Ha);
    get_p();
    while (T--){
        scanf("%d%d",&n,&m);
        ans=(long long)h[m]*g[n]%Ha;
        printf("%d\n",ans);
    }
}

prompt

  • The issue of modulo should be considered carefully.
  • The inverse element is actually only 1~Ha-1 that needs to be calculated, and the inverse elements of other numbers can be expressed as 1/(i%Ha)
  • The first time I paid MLE...

Guess you like

Origin blog.csdn.net/jackypigpig/article/details/78372259