记录编号 26938 评测结果 AAAAAAAAAA
题目名称 sumcount 最终得分 100
用户昵称 Gravatar老虎小飞 是否通过 通过
代码语言 Pascal 运行时间 2.579 s
提交时间 2011-07-29 18:20:27 内存使用 45.89 MiB
显示代码纯文本
var
p,pre,num:array[0..2000000]of int64;
n,m,a,b,i,j,q,t:longint;
ans,ans0:int64;

function ksm(a,k:int64):int64;
var
kk:int64;
begin
    if k=0 then exit(1);
    if k=1 then exit(a);
    kk:=ksm(a,k div 2);
    kk:=kk*kk;
    if odd(k) then kk:=kk*a;
    exit(kk);
end;

function min(a,b:int64):int64;
begin
    if a>b then exit(b);
    exit(a);
end;

function cc(m,n:int64):int64;
var
i:longint;
a,b,c:int64;
begin
    fillchar(num,sizeof(num),0);
    a:=min(m,n-m);
    b:=n-a;
    c:=1;
    for i:=2 to a do num[i]:=-1;
    for i:=n downto b+1 do begin
        if pre[i]=0 then begin
            c:=c*ksm(i,num[i]+1);
            if c>q*10 then c:=c mod q;
        end
        else begin
            inc(num[i]);
            inc(num[pre[i]],num[i]);
            inc(num[i div pre[i]],num[i]);
        end;
    end;
    for i:=b downto 2 do begin
        if pre[i]=0 then begin
            c:=c*ksm(i,num[i]);
            if c>q*10 then c:=c mod q;
        end
        else begin
            //inc(num[i]);
            inc(num[pre[i]],num[i]);
            inc(num[i div pre[i]],num[i]);
        end;
    end;
    exit(c);
end;

begin
assign(input,'sumcount.in');reset(input);
assign(output,'sumcount.out');rewrite(output);
    read(n,a,b,q);
    for i:=2 to b+n do begin
        if pre[i]=0 then begin
            inc(t);p[t]:=i;
        end;
        for j:=1 to t do begin
            if i*p[j]>b+n then break;
            pre[i*p[j]]:=p[j];
            if i mod p[j]=0 then break;
        end;
    end;
    ans:=cc(n,b+n);
    if a>0 then ans0:=cc(n,a+n-1)
    else ans0:=0;
    writeln((ans-ans0+q) mod q);
close(input);close(output);
end.