bzoj1485

首先考虑dp,设f[i,j]表示1~i用过了,期中j个放在偶数位然后转移大家都会

这显然TLE,我们观察这个dp,任意前i个数,无论怎么放,放在奇数位的数的个数一定要大于等于放在偶数位的个数

于是很明显这是经典的卡特兰数模型

注意这里涉及到了除法取模,而模数不一定是质数

很显然的想法是分解质因数然后约分

但有更漂亮的做法,http://blog.csdn.net/jasonzhu8/article/details/5949622

 1 var v,b,p:array[0..2000010] of longint;
 2     n,i,j,mo,t:longint;
 3     ans:int64;
 4 
 5 procedure calc(x,w:longint);
 6   begin
 7     while v[x]<>0 do
 8     begin
 9       inc(b[v[x]],w);
10       x:=x div v[x];
11     end;
12     inc(b[x],w);
13   end;
14 
15 function quick(x:int64;y:longint):int64;
16   begin
17     quick:=1;
18     while y>0 do
19     begin
20       if y mod 2=1 then quick:=quick*x mod mo;
21       y:=y div 2;
22       x:=x*x mod mo;
23     end;
24   end;
25 
26 begin
27   readln(n,mo);
28   for i:=2 to 2*n do
29   begin
30     if v[i]=0 then
31     begin
32       inc(t);
33       p[t]:=i;
34     end;
35     for j:=1 to t do
36     begin
37       if int64(i)*int64(p[j])>2*n then break;
38       v[i*p[j]]:=p[j];
39       if i mod p[j]=0 then break;
40     end;
41   end;
42   for i:=n+2 to 2*n do
43     calc(i,1);
44   for i:=2 to n do
45     calc(i,-1);
46   ans:=1;
47   for i:=1 to t do
48     ans:=ans*quick(p[i],b[p[i]]) mod mo;
49   writeln(ans);
50 end.
View Code
原文地址:https://www.cnblogs.com/phile/p/4489857.html