/* Авторское решение к областной олимпиаде по информатике
16 февраля 2002 г. Запорожье.
(с) Ильяшенко Матвей 2002 г.
*/
#include <stdio.h>
#include <string.h>
#ifndef lenL
// Размер по умолчанию массива, содержащего длинное число
#define lenL 45
#endif
/*
* Функции дублирования содержимого массива длинного числа
* (содержимое копируется из src в dest)
* *dest,*src - указатели на массивы длинных чисел
*/
void cpyL(short *dest,short *src)
{ int i;
for(i=0;i<lenL;i++)
dest[i]=src[i];
}
inline void dupL(short *dest,short *src)
{ cpyL(dest,src); }
/*
* Функция обнуления части элементов массива длинного числа
* *a - указатель на массив длинного числа
* from=0 - первый элемент, подлежащий обнулению
* to=lenL-1 - последний элемент +1, подлежащий обнулению
*/
void nullL(short *a,int from=0,int to=lenL)
{ int i;
for(i=from;i<to;i++)
a[i]=0;
}
/*
* Функция определения первого значащего разряда длинного числа
* *a - указатель на массив длинного числа
* Возврат:
* Номер первого значащего разряда
* Если число равно 0, то возвращается 0
*/
int firstL(short *a)
{ int i;
for(i=lenL-1;i>=0;i--)
if(a[i]!=0)
return(i);
return(0);
}
/*
* Функция сравнения двух длинных чисел
* *a,*b - указатели на массивы длинных чисел
* Возврат:
* 1 - если a>b
* 0 - если a=b
* -1 - если a
int cmpL(short *a,short *b)
{ int i;
for(i=lenL-1;i>=0;i--)
{ if(a[i]>b[i]) return(1);
if(a[i]<b[i]) return(-1);
}
return(0);
}
/*
* Функция вывода длинного числа на stdout
* *a - указатель на массив длинного числа
*/
void writeL(short *a)
{ int i,first;
first=firstL(a);
printf("%d",a[first]);
for(i=first-1;i>=0;i--)
printf("%04d",a[i]);
}
/*
* Функция здвига числа влево
* *a - указатель на массив длинного числа
* n - количество разрядов, на которое сдвигается число
*/
void shlL(short *a,int n)
{ int i;
for(i=lenL-1;i>=n;i--)
a[i]=a[i-n];
nullL(a,0,n);
}
/*
* Функция добавления к длинному числу числа типа short
* *a - указатель на массив длинного числа
* n - добавляемое число (оно же является переполнением)
* Возврат:
* 0 - не было переполнения
* 1 - было переполнение
*/
int addL(short *a,short n)
{ int i=0;
long sum;
do
{ sum=(long)(a[i])+(long)(n);
a[i]=(short)(sum%10000L);
n=(short)(sum/10000L);
i++;
}while((i!=lenL)&&(n!=0));
return((int)(n));
}
/*
* Функция добавления к длинному числу a длинного числа b
* *a,*b - указатели на массивы длинных чисел
* Возврат:
* 0 - не было переполнения
* 1 - было переполнение
*/
int addL(short *a,short *b)
{ int i=0;
short n=0;
long sum;
do
{ sum=(long)(a[i])+(long)(b[i])+(long)(n);
a[i]=(short)(sum%10000L);
n=(short)(sum/10000L);
i++;
}while(i!=lenL);
return((int)(n));
}
/*
* Функция умножения длинного числа на число типа short
* *a - указатель на массив длинного числа
* n - добавляемое число (оно же является переполнением)
* Возврат:
* 0 - не было переполнения
* 1 - было переполнение
*/
int mulL(short *a,short n)
{ int i;
short p=0;
long mul;
for(i=0;i<lenL;i++)
{ mul=(long)(a[i])*(long)(n)+(long)(p);
a[i]=(short)(mul%10000L);
p=(short)(mul/10000L);
}
return((int)(p));
}
/*
* Функция умножения длинного числа a на длинное число b
* *a,*b - указатели на массивы длинных чисел
* Возврат:
* 0 - не было переполнения
* 1 - было переполнение
*/
int mulL(short *a,short *b)
{ int i,first_b,res=0;
short t[lenL],r[lenL];
nullL(r);
first_b=firstL(b);
for(i=0;i<=first_b;i++)
if(b[i]!=0)
{ cpyL(t,a);
shlL(t,i);
mulL(t,b[i]);
if(addL(r,t)) res=1;
}
cpyL(a,r);
return(res);
}
/*
* Функция возведения числа x в степень y
* *a - указатель на длинное число, в которое будет записан результат
* x - основание степени
* y - показатель степени
* Возврат:
* 0 - не было переполнения
* 1 - было переполнение
*/
int powL(short *a,int x,int y)
{ int i,res=0;
nullL(a); addL(a,1);
for(i=0;i<y;i++)
res+=mulL(a,x);
return((int)(res>0));
}
short Table[2][180][lenL];
short Result[90][lenL];
void main()
{ short Sum[lenL],t[lenL],pow[lenL];
long N,K,i,j,k,Pmax;
scanf("%ld%ld",&N,&K);
Pmax=N/2;
for(j=0;j<=N;j++)
{ nullL(Table[0][j]); addL(Table[0][j],1); }
nullL(Result[0]); addL(Result[0],1);
for(i=1;i<=Pmax;i++)
{ for(j=i*2;j<=N;j++)
{ nullL(Table[i%2][j]);
for(k=(i-1)*2;k<=j-2;k++)
addL(Table[i%2][j],Table[(i-1)%2][k]);
}
dupL(Result[i],Table[i%2][N]);
}
nullL(Sum);
powL(pow,K-1,N-Pmax-1);
for(i=0;i<=Pmax;i++)
{ mulL(pow,K-1);
dupL(t,pow);
mulL(t,Result[Pmax-i]);
addL(Sum,t);
}
writeL(Sum);
printf("\n");
}
|
Комментарии
|
Реклама:
Разработано в студии "Webous" — о проекте — сайта карта —Реклама: