题意:OI大师抖儿在夺得银牌之后,顺利保送pku。这一天,抖儿问长者:“虽然我已经保送了,但是我还要参加学考。马上就要考政治了,请问应该怎样学习哲学,通过政治考试?”

 长者回答:“你啊,Too Young Too Simple,Sometimes Naive!哲学这种东西,不是说想懂就能懂的,需要静心撕烤。你去后面的森林里好好想想。”
长者的后院有一片哲♂学森林。由于一些奥妙重重的原因,这片森林构成了一个n*m的矩形,其中每个点就代表了一棵树。此外,由于辣鸡出题人KJDH从中捣鬼,有些树被连根拔起(也就是消失了)。抖儿每天都要到树下撕烤,因此他想要在每一行选择一棵树。但是他非常讨厌走回头路,因此第i行选择的树必须比第i-1行的靠右。现在抖儿想知道,总共有多少种选择的方案 mod 1000003。
对于所有的数据,保证n,m≤10^9,p≤min(n*m,2000)
 
思路:出题人lyy系列
【NOIP2017练习】怎样学习哲学(计数,DP)-LMLPHP

【NOIP2017练习】怎样学习哲学(计数,DP)-LMLPHP

【NOIP2017练习】怎样学习哲学(计数,DP)-LMLPHP

【后记】
在经历了长久的撕烤之后,抖儿终于领悟了哲♂学奥义。
抖儿对长者说:“我知道了!哲学源于生活,只有撕烤生活,才能领悟哲理。”
长者嘿嘿一笑:“你想多了。因为你在哲♂学之森中待的时间太长,政治学考已经在一个月前结束了。”
 const mo=;
var x,y:array[..]of longint;
dp:array[..]of int64;
fac,exf:array[..mo]of int64;
n,m,i,p,j:longint; procedure swap(var x,y:longint);
var t:longint;
begin
t:=x; x:=y; y:=t;
end; procedure qsort(l,r:longint);
var i,j,mid1,mid2:longint;
begin
i:=l; j:=r; mid1:=x[(l+r)>>]; mid2:=y[(l+r)>>];
repeat
while (mid1>x[i])or((mid1=x[i])and(mid2>y[i])) do inc(i);
while (mid1<x[j])or((mid1=x[j])and(mid2<y[j])) do dec(j);
if i<=j then
begin
swap(x[i],x[j]);
swap(y[i],y[j]);
inc(i); dec(j);
end;
until i>j;
if l<j then qsort(l,j);
if i<r then qsort(i,r);
end; function c(n,m:longint):int64;
begin
if (n<m)or(m<) then exit();
if (n<=mo)and(m<=mo) then exit(fac[n]*exf[m] mod mo*exf[n-m] mod mo);
exit(c(n div mo,m div mo)*c(n mod mo,m mod mo) mod mo);
end; begin
assign(input,'zhexue.in'); reset(input);
assign(output,'zhexue.out'); rewrite(output);
readln(n,m,p);
for i:= to p do read(x[i],y[i]);
fac[]:=; exf[]:=; exf[]:=;
for i:= to mo do fac[i]:=fac[i-]*i mod mo;
for i:= to mo do exf[i]:=exf[mo mod i]*(mo-mo div i) mod mo;
for i:= to mo do exf[i]:=exf[i-]*exf[i] mod mo;
inc(p); x[p]:=n+; y[p]:=m+;
qsort(,p);
for i:= to p do
begin
dp[i]:=c(y[i]-,x[i]-);
for j:= to i- do
if (x[j]<x[i])and(y[j]<y[i]) then
dp[i]:=(dp[i]-dp[j]*c(y[i]-y[j]-,x[i]-x[j]-) mod mo) mod mo;
dp[i]:=(dp[i] mod mo+mo) mod mo;
end;
writeln(dp[p]);
close(input);
close(output);
end.
 
05-28 01:21