如果发现广告等破坏行为,请尽量将条目恢复到较早的版本而不是把相应内容直接删除,谢谢合作。
URAL/1036
来自"NOCOW"
< URAL
f[i,j]表示有i位,每位之和为j的方案数f[i,j]=sigma(f[i-1,j-k]) , 0<=k<=9.如果给出的s为奇数,直接输出0,否则根据组合知识,ans=f[n,s div 2]^2. 加上高精度即可。
program cao; const maxn=100; type int128=array[0..maxn+1] of longint; var f:array[0..60,-10..1000] of int128; ans,tmp:int128; a,b,c,d,e,g,h,i,j,k,l,n,m,p,q:longint; s:string; procedure init; begin read(n,m); end; function jia(a,b:int128):int128; var i,j:longint; begin tmp[maxn+1]:=0; for i:=1 to maxn do tmp[i]:=a[i]+b[i]; for i:=maxn downto 1 do begin tmp[i]:=tmp[i]+tmp[i+1] div 10000; tmp[i+1]:=tmp[i+1] mod 10000; end; exit(tmp); end; function cheng(a:int128):int128; var i,b:longint; begin for i:=1 to maxn do if a[i]<>0 then break; b:=i; fillchar(tmp,sizeof(tmp),0); for i:=maxn downto b do for j:=maxn downto b do inc(tmp[i+j-maxn],a[i]*a[j]); for i:=maxn downto 1 do begin tmp[i]:=tmp[i]+tmp[i+1] div 10000; tmp[i+1]:=tmp[i+1] mod 10000; end; exit(tmp); end; procedure main; begin if odd(m) then exit; m:=m shr 1; f[0,0][maxn]:=1; for i:=1 to n do for j:=0 to m do for k:=0 to 9 do f[i,j]:=jia(f[i,j],f[i-1,j-k]); ans:=cheng(f[n,m]); end; procedure print; begin for i:=1 to maxn do if ans[i]<>0 then break; str(ans[i],s); write(s); for i:=i+1 to maxn do begin str(ans[i],s); while length(s)<4 do insert(‘0′,s,1); write(s); end; writeln; end; begin init; main; print; end.
用滚动数组要不然有可能爆空间
#include <iostream> #include <stdlib.h> #include <string> #include <iomanip> using namespace std; class Bigint { public: static const int sa = 200; int * da; ~Bigint(); Bigint(const int n); Bigint(const Bigint &a); Bigint operator=(const int n); Bigint operator=(const Bigint &a); Bigint operator+(const Bigint &b); Bigint operator*(const Bigint &b); friend ostream &operator<<(ostream &s, Bigint &a); friend istream &operator>>(istream &s, const Bigint &a); }; Bigint::~Bigint() { delete [] da; } Bigint::Bigint(const int n = 0) { da = new int[sa]; memset(da, 0, sizeof(int) * sa); da[1] = n; int i; for(i = 1 ; da[i] ; i++) { da[i + 1] += da[i] / 10000; da[i] %= 10; } da[0] = i - 1; } Bigint::Bigint(const Bigint &a) { da = new int[sa]; memcpy(da, a.da, sizeof(int) * sa); } Bigint Bigint::operator=(const Bigint &a) { memcpy(da, a.da, sizeof(int) * sa); return *this; } Bigint Bigint::operator=(const int n) { Bigint c(n); *this = c; return *this; } Bigint Bigint::operator+(const Bigint &b) { Bigint &a = *this; Bigint c; c.da[0] = max(a.da[0], b.da[0]); int i; for(i = 1 ; i <= c.da[0] ; i++) { c.da[i] += a.da[i] + b.da[i]; c.da[i + 1] += c.da[i] / 10000; c.da[i] %= 10000; } c.da[0] = i; while(c.da[c.da[0]] == 0 && c.da[0] > 1) c.da[0]--; return c; } Bigint Bigint::operator*(const Bigint &b) { Bigint &a = *this; Bigint c; int i, j; for(i = 1 ; i <= a.da[0] ; i++) for(j = 1 ; j <= b.da[0] ; j++) { c.da[i + j - 1] += a.da[i] * b.da[j]; c.da[i + j] += c.da[i + j - 1] / 10000; c.da[i + j - 1] %= 10000; } c.da[0] = a.da[0] + b.da[0]; while(c.da[c.da[0]] == 0 && c.da[0] > 1) c.da[0]--; return c; } ostream &operator<<(ostream &s, Bigint a) { int i, l; l = a.da[0]; s << a.da[l]; for(i = l - 1 ; i >= 1 ; i--) s << setfill('0') << setw(4) << a.da[i]; return s; } istream &operator>>(istream &s, Bigint &a) { int k, i; s >> k; Bigint c(k); a = c; return s; } int n,m; //long long f[51][1001]; Bigint f[2][1001]; void work() { cin >> n >> m; if(m % 2 == 1) { cout << 0 << endl; return; } f[0][0] = 1; m /= 2; for(int i = 1 ; i <= n ; i++) for(int j = 0 ; j <= m ; j++) { f[i % 2][j] = 0; for(int k = 0 ; k <= 9 ; k++) { if(j - k >= 0) f[i % 2][j] = f[i % 2][j] + f[(i - 1) % 2][j - k]; } } cout << (f[n % 2][m] * f[n % 2][m]) << endl; } int main() { work(); return 0; }