NOIP常用算法代码
(Pascal)
1.数论算法
//1.1 最大公约数gcd function
gcd(a,b:longint):longint; begin
if b=0 then exit(a) else exit(gcd(b,a mod b));
end;
//1.2 最小公倍数lcm function
lcm(a,b:longint):longint; begin
lcm:=a div gcd(a,b)*b; end;
//notice:要先除后乘,避免溢出//1.3.1 快速幂运算pow function
pow(x,n:longint):longint; begin
if n=0 then exit(1);
pow:=pow(x,n div 2);
pow:=pow*pow;
if (n and 1)=1 then pow:=pow*x;
end;
//1.3.2 快速幂运算pow (mod P)
function
pow(x,n,P:longint):longint;ov erload;
begin
if n=0 then exit(1);
pow:=pow(x,n div 2,P);
pow:=int64(pow)*pow mod P; //注意小心溢出
if (n and 1)=1 then pow:=int64(pow)*x mod P;
end;
//1.3.3 快速幂非递归function
pow0(x,n:longint):longint; var result:longint;
begin
result:=1;
while n<>0 do
begin
if (n and 1)=1 then result:=result*x;
x:=x*x; n:=n shr 1;
end;
exit(result);
end;
//1.4 朴素判断素数is_prime function
is_prime(x:longint):boolean; var i:longint;
begin
for i:=2 to round(sqrt(x)) do
if x mod i=0 then
exit(false);
if x<2 then exit(false) else exit(true);
end;
//1.5 素数的筛法procedure
get_prime(n:longint);//计算1-n之间的素数,存储在list数组中
var i,j:longint;
begin
for i:=2 to n do if not f[i] then
begin
inc(top);
list[top]:=i;
j:=i+i;
while j<=n do
begin
f[j]:=true;
inc(j,i);
end;
end;
end;
//1.5.2 素数的筛选加强版program prime2; const maxn=40000;
maxm=100001;
var l,r,i,j:longint;
f:array[0..maxn] of boolean;
q:array[0..maxm] of boolean;
begin
fillchar(f,sizeof(f),false); for i:=2 to
round(sqrt(maxn)) do if not f[i] then
begin j:=i+i;
while j<=maxn do begin
f[j]:=true;
inc(j,i);
end;
end;
readln(l,r);
for i:=2 to
round(sqrt(maxn)) do if not f[i] then
begin
j:=l-l mod i;
if j begin q[j-l]:=true; inc(j,i); end; end; if l=1 then q[0]:=true; for i:=l to r do if not q[i-l] then writeln(i); end. //1.6 模运算下的除法(mod P) // a/b mod P = a*b^(P-2) mod P function divide(a,b,P:longint):longint; begin divide:=a*pow(b,P-2,P) mod P; end; //1.7求组合数 program zuheshu; var n,m,i,j,k:longint; c:array[0..100,0..100] of longint; function c1(n,m:longint):int64; var i,j:longint; ans:int64; begin ans:=1; for i:=n-m+1 to n do begin j:=i; ans:=int64(ans)*j div (j-n+m); end; exit(ans); end; function gcd(a,b:longint):longint; begin if b=0 then exit(a) else exit(gcd(b,a mod b)); end; function c2(n,m:longint):longint; var i,j,s,t,ans,x:longint; a,b:array[1..100] of longint; begin s:=0; for i:=m+1 to n do begin inc(s); a[s]:=i; end; for i:=1 to n-m do b[i]:=i; for i:=1 to n-m do begin if a[i]=1 then continue; for j:=1 to n-m do begin if b[j]=1 then continue; t:=gcd(a[i],b[j]); a[i]:=a[i] div t; b[j]:=b[j] div t; end; end; ans:=1; for i:=1 to n-m do ans:=ans*a[i]; exit(ans); end; begin readln(n,m); c[0,0]:=1; for i:=0 to n do c[i,0]:=1; for i:=1 to n do for j:=1 to n do c[i,j]:=c[i-1,j]+c[i-1,j-1]; writeln(c[n,m]); writeln(c1(n,m)); writeln(c2(n,m)); end. 2.高精度运算 const NUMLEN = 100; //高精度数长度 DLEN = 4; //压位长度 MM = 10000; //压位进制// ps.若有乘法建议设置DLEN=3,MM=1000 type bignum = array[0..NUMLEN]of longint; var a,b,c:bignum; s:ansistring; procedure print(var a:bignum); var i:longint; begin write(a[a[0]]); for i:=a[0]-1 downto 1 do begin if a[i]<1000 then write(0); //若MM=1000,注释掉本行 if a[i]<100 then write(0); if a[i]<10 then write(0); write(a[i]); end; writeln; end; operator + (var a,b:bignum)c:bignum; var i:longint; begin fillchar(c,sizeof(c),0); if a[0]>b[0] then c[0]:=a[0] else c[0]:=b[0]; for i:=1 to c[0] do begin inc(c[i],a[i]+b[i]); if c[i]>=MM then begin dec(c[i],MM); inc(c[i+1]); end; end; if c[c[0]+1]<>0 then inc(c[0]); end; operator - (var a,b:bignum)c:bignum; var i:longint; begin fillchar(c,sizeof(c),0); c[0]:=a[0]; for i:=1 to c[0] do begin inc(c[i],a[i]-b[i]); if c[i]<0 then begin inc(c[i],MM); dec(c[i+1]); end; end; while (c[0]>1) and (c[c[0]]=0) do dec(c[0]); end; operator * (var a,b:bignum)c:bignum;var i,j:longint; begin fillchar(c,sizeof(c),0); c[0]:=a[0]+b[0]-1; for i:=1 to a[0] do for j:=1 to b[0] do inc(c[i+j- 1],a[i]*b[j]); for i:=1 to c[0] do begin inc(c[i+1],c[i] div MM); c[i]:=c[i] mod MM; end; if c[c[0]+1]<>0 then inc(c[0]); end; procedure convert(var a:bignum;b:longint);overload; begin fillchar(a,sizeof(a),0); repeat inc(a[0]); a[a[0]]:=b mod MM; b:=b div MM; until b=0; end; procedure convert(var a:bignum;s:ansistring);overlo ad; var i,t,n:longint; begin n:=length(s); a[0]:=(n-1)div DLEN+1; for i:=1 to n do begin t:=(n-i)div DLEN+1; a[t]:=a[t]*10+ord(s[i])-ord('0'); end; end; begin readln(s); convert(a,s); readln(s); convert(b,s); c:=a*b; print(c); end. 3.排序 //3.1 排序算法 quicksort procedure sort(l,r:longint); var i,j,tmp,mid:longint; begin i:=l; j:=r; mid:=a[(l+r+r)div 3]; while i<=j do begin while a[i] inc(i); while a[j]>mid do dec(j); if i<=j then begin tmp:=a[i]; a[i]:=a[j]; a[j]:=tmp; inc(i); dec(j); end; end; if i if l end; //3.2 双关键字快排procedure multi_sort(l,r:longint); var i,j,tmp,mid0,mid1:longint; begin i:=l; j:=r; mid0:=a[(l+r+r)div 3]; mid1:=b[(l+r+r)div 3]; while i<=j do begin while (a[i] while (a[j]>mid0) or ((a[j]=mid0)and(a[j]>mid1)) do dec(j); if i<=j then begin tmp:=a[i]; a[i]:=a[j]; a[j]:=tmp; tmp:=b[i]; b[i]:=b[j]; b[j]:=tmp; inc(i); dec(j); end; end; if i if l //3.3插入排序 procedure insert_sort; var i,j:longint; begin for i:=2 to n do begin a[0]:=a[i]; j:=i-1;