如果发现广告等破坏行为,请尽量将条目恢复到较早的版本而不是把相应内容直接删除,谢谢合作。

URAL/1036

来自"NOCOW"

跳转到: 导航, 搜索

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;
}
个人工具