沙拉公主的困惑 cash

一、沙拉公主的困惑
(cash.pas/c/cpp, 限时3 秒,内存256M)
【题目描述】
大富翁国因为通货膨胀,以及假钞泛滥,政府决定推出一项新的政策:现有钞票编
号范围为1 到N 的阶乘,但是,政府只发行编号与M!互质的钞票。房地产第一大户沙拉
公主决定预测一下大富翁国现在所有真钞票的数量。现在,请你帮助沙拉公主解决这个
问题,由于可能张数非常大,你只需计算出对R 取模后的答案即可。R 是一个质数。
【输入文件】
第一行为两个整数T,R。R<=10^9+10,T<=10000,表示该组中测试数据数目,R 为
模,
后面T 行,每行一对整数N,M,见题目描述
【输出文件】

共T 行,对于每一对N,M,输出1 至N!中与M!素质的数的数量对R 取模后的值

【样例】
输入样例(cash.in 的内容):
1 11
4 2
输出样例(cash.out 的内容):
1
【数据范围】
对于20%的数据, 1<=N,M<=10,T<=10
对于40%的数据, 1<=N,M<=10000
对于80%的数据, 1<=N,M<=1000000
对于100%的数据,1<=N,M<=10000000


山东省选08年第二轮第一天试题

N!*(小于M的质数减一之积)/(小于M的质数之积)

需要注意的是预处理10000000以内质数用一次循环,

i从i倍开始设为合数


测试数据

http://mail.qq.com/cgi-bin/ftnExs_download?k=253732389632cc9c361047271e33014c520702080103044c4c55540952560356571a065b5255195706010715080b04004e53560b5057070150520b0904333c63005641501f4155116371&t=exs_ftn_download&code=c728134c


program cash;
const
  maxn=10000000;
var
  t,r,n,m,i,j,k:longint;
  ans:int64;
  left,mix,om:array [0..maxn+1] of int64;
  yes:array [0..maxn+1] of boolean;

function quick (x,y:int64):int64;
var
  i:int64;
begin
  if y=0 then exit(1);
  if y=1 then exit(x mod r);
  i:=quick(x,y div 2);
  if y and 1 = 1 then exit(i * i mod r * x mod r)
                 else exit(i * i mod r);
end;

begin
  assign(input,'cash.in');
  reset(input);
  assign(output,'cash.out');
  rewrite(output);
  read(t,r);
  left[1]:=1;
  for i:=2 to maxn do
    left[i]:=left[i-1]*i mod r;
  fillchar(yes,sizeof(yes),false);
  for i:=2 to maxn do
    if not yes[i] then
      for j:=i to maxn div i do
        yes[i*j]:=true;
  mix[1]:=1;
  for i:=2 to maxn do
    begin
      mix[i]:=mix[i-1];
      if not yes[i] then mix[i]:=mix[i]*(i-1) mod r;
    end;
  om[1]:=1;
  for i:=2 to maxn do
   begin
     om[i]:=om[i-1];
     if not yes[i] then om[i]:=om[i]*i mod r;
   end;
  while t<>0 do
    begin
      dec(t);
      read(n,m);
      if m=1 then
        begin
          writeln(left[n]);
          continue;
        end;
      if n=1 then
        begin
          writeln(1 mod r);
          continue;
        end;
      writeln(left[n]*mix[m] mod r *quick(om[m],r-2) mod r);
    end;
  close(input);
  close(output);
end.


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值