BZOJ2227: [Zjoi2011]看电影(movie)

来源:互联网 发布:网络挣钱是真的吗 编辑:程序博客网 时间:2024/06/06 01:17

  题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2227

  组合数学,加上一个位置,可以看成是一个环,方案数(k+1)^n,是环就可以转,那么就有k+1个方案重复,故实际方案数为(k+1)^(n-1),再把这个位置去掉,方案数为k+1-n,所以对于这个问题本身来说,方案数为(k+1)^n·(k+1)^(n-1),总方案数为k^n,则概率为方案数/总方案数。

  关于输出,因为要约分来着,这题显然需要高精度,就直接分解质因子即可。但是事实上k+1和k互质,所以可以直接把k+1-n拎出来约分就好了。

  输出可以压位,但实际上不压位也能过,但是一定要注意输出长度

  贴代码

 const tt=10;maxn=205; type arr=array[0..600]of longint; var n,k,x,y,Q,dt,i,j,t:longint;     ans1,ans2:arr;     vis:array[0..maxn]of boolean;     prime,g,f:array[0..50]of longint; function mul(a,b:arr):arr;  var i,j:longint;      c:arr;   begin    fillchar(c,sizeof(c),0);    c[0]:=a[0]+b[0];    for i:=1 to a[0] do     for j:=1 to b[0] do      begin       inc(c[i+j-1],a[i]*b[j]);       inc(c[i+j],c[i+j-1] div tt);       c[i+j-1]:=c[i+j-1] mod tt;      end;    while (c[c[0]]=0)and(c[0]>1) do dec(c[0]);    exit(c);   end; function power(a,b:longint):arr;  var s,w:arr;   begin    s[0]:=1;s[1]:=1;    if trunc(ln(a)/ln(10))+1=1 then begin w[0]:=1;w[1]:=a; end;    if trunc(ln(a)/ln(10))+1=2 then begin w[0]:=2;w[2]:=a div 10;w[1]:=a mod 10; end;    if trunc(ln(a)/ln(10))+1=3 then begin w[0]:=3;w[3]:=a div 100;w[2]:=(a div 10) mod 10;w[1]:=a mod 10; end;    while b<>0 do     begin      if b and 1=1 then s:=mul(s,w);      w:=mul(w,w);      b:=b>>1;     end;    exit(s);   end; begin  assign(input,'movie.in');reset(input);  assign(output,'movie.out');rewrite(output);  fillchar(vis,sizeof(vis),1);  for i:=2 to trunc(sqrt(maxn)) do   if vis[i] then    for j:=2 to maxn div i do vis[i*j]:=false;  prime[0]:=0;  for i:=2 to maxn do   if vis[i] then begin                   inc(prime[0]);                   prime[prime[0]]:=i;                  end;  readln(Q);  for t:=1 to Q do   begin    readln(n,k);    if k+1-n<=0 then begin writeln(0,' ',1);continue; end;    fillchar(g,sizeof(g),0);    fillchar(f,sizeof(f),0);    for i:=1 to prime[0] do     begin      if (k+1)mod prime[i]=0 then begin                                   x:=k+1;                                   while x mod prime[i]=0 do                                    begin                                     inc(g[i],n-1);                                     x:=x div prime[i];                                    end;                               end;      if (k+1-n)mod prime[i]=0 then begin                                     x:=k+1-n;                                     while x mod prime[i]=0 do                                      begin                                       inc(g[i]);                                       x:=x div prime[i];                                      end;                                    end;      if k mod prime[i]=0 then begin                                x:=k;                                while x mod prime[i]=0 do                                 begin                                  inc(f[i],n);                                  x:=x div prime[i];                                 end;                               end;     end;     ans1[0]:=1;ans1[1]:=1;     ans2[0]:=1;ans2[1]:=1;     for i:=1 to prime[0] do      begin       if f[i]<g[i] then dt:=f[i] else dt:=g[i];       dec(f[i],dt);dec(g[i],dt);       if g[i]<>0 then ans1:=mul(ans1,power(prime[i],g[i]));       if f[i]<>0 then ans2:=mul(ans2,power(prime[i],f[i]));      end;     for i:=ans1[0] downto 1 do write(ans1[i]);     write(' ');     for i:=ans2[0] downto 1 do write(ans2[i]);writeln;    end;   close(input);close(output);  end.
【写的有漏洞的,欢迎路过大神吐槽】

  2017/3/13 14:16:05

  Ending.



0 0
原创粉丝点击