bzoj 2186 [Sdoi2008]沙拉公主的困惑

 

我们根据欧几里得定理可以知道

(a,b)=(b,a mod b)也可以得到

(a+b,b)=(b,(a+b) mod b)=(b,a)=(a,b)

直观点说就是两个数a,b的gcd,和a+b,b的gcd是相等的

那么我们可以知道phi(m!)也就是与1-m!中与m!互质的数,

那么对于每个互质的数,我们加上m!,就可以得到一个新的

和m!互质的数,所以对于每个1-m!与m!互质的数

n!范围内一共可以得到n!/m!组解,那么一共也就是phi(m!)*(n!/m!)

可以将phi(m!)用公式展开化简,在此不再赘述

/**************************************************************
    Problem: 2186
    User: BLADEVIL
    Language: Pascal
    Result: Accepted
    Time:9524 ms
    Memory:248272 kb
****************************************************************/
 
//By BLADEVIL
var
    t, r                        :longint;
    i                           :longint;
    prime                       :array[0..1000001] of longint;
    flag                        :array[0..10000001] of boolean;
    fac, pi1, pi2               :array[0..10000001] of int64;
    x, y                        :int64;
     
procedure make;
var
    i, j                        :longint;
begin
    fac[0]:=1;
    flag[1]:=true;
    for i:=1 to 10000000 do fac[i]:=fac[i-1]*int64(i) mod r;
    for i:=2 to 10000000 do
    begin
        if not flag[i] then
        begin
            inc(prime[0]);
            prime[prime[0]]:=i;
        end;
        for j:=1 to prime[0] do
        begin
            if i*prime[j]>10000000 then break;
            flag[i*prime[j]]:=true;
            if i mod prime[j]=0 then break;
        end;
    end;
    pi1[0]:=1; pi2[0]:=1;
    for i:=1 to 10000000 do
    begin
        pi1[i]:=pi1[i-1];
        if not flag[i] then pi1[i]:=pi1[i]*int64(i-1) mod r; 
    end;
    for i:=1 to 10000000 do
    begin
        pi2[i]:=pi2[i-1];
        if not flag[i] then pi2[i]:=pi2[i]*int64(i) mod r; 
    end;
end;
 
procedure ex_gcd(a,b:int64);
var
    z                           :int64;
begin
    if b=0 then
    begin
        x:=1; y:=0; exit;
    end;
    ex_gcd(b,a mod b);
    z:=x;
    x:=y;
    y:=z-(a div b)*y;
end;
     
function gcd(a:int64):int64;
begin
    ex_gcd(a,r);
    gcd:=(x mod r+r) mod r;
end;
     
procedure main;
var
    i                           :longint;
    ans                         :int64;
    n, m                        :longint;
begin
    read(n,m);
    ans:=fac[n];
    ans:=ans*pi1[m] mod r;
    ans:=ans*gcd(pi2[m]) mod r;
    writeln(ans);
end;
 
begin
    read(t,r);
    make;
    for i:=1 to t do main;
end.
 

 

posted on 2013-12-25 11:39  BLADEVIL  阅读(952)  评论(0编辑  收藏  举报