题目描述
设r是个2^k 进制数,并满足以下条件:
(1)r至少是个2位的2^k 进制数。
(2)作为2^k 进制数,除最后一位外,r的每一位严格小于它右边相邻的那一位。
(3)将r转换为2进制数q后,则q的总位数不超过w。
在这里,正整数k(1≤k≤9)和w(k
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
struct num
{
int l,a[30];
num operator + (const num &x) const
{
num ans;
int len;
memset(ans.a,0,sizeof(ans.a));
for (int i=1;i<=l||i<=x.l;i++)
{
ans.a[i]+=a[i]+x.a[i];
ans.a[i+1]+=ans.a[i]/10000;
ans.a[i]%=10000;
}
if (l<x.l) len=x.l+1;
else len=l+1;
while (!ans.a[len]&&len) len--;
ans.l=len;
return ans;
}
num operator - (const num &x) const
{
num ans;
memset(ans.a,0,sizeof(ans.a));
for (int i=1;i<=l;i++)
{
ans.a[i]+=a[i]-x.a[i];
if (ans.a[i]<0)
{
ans.a[i]+=10000;
ans.a[i+1]--;
}
}
ans.l=l;
while (!ans.a[ans.l]&&ans.l) ans.l--;
return ans;
}
num operator * (const num &x) const
{
num ans;
memset(ans.a,0,sizeof(ans.a));
int len;
for (int i=1;i<=l;i++)
for (int j=1;j<=x.l;j++)
{
ans.a[i+j-1]+=a[i]*x.a[j];
ans.a[i+j]+=ans.a[i+j-1]/10000;
ans.a[i+j-1]%=10000;
}
len=l+x.l;
while (!ans.a[len]&&len) len--;
ans.l=len;
return ans;
}
}c[521][521],ans;
void print(num x)
{
printf("%d",x.a[x.l]);
for (int i=x.l-1;i>=1;i--)
{
int y=x.a[i];
if (y<1000) printf("0");
if (y<100) printf("0");
if (y<10) printf("0");
printf("%d",y);
}
printf("\n");
}
int k,w;
int star,big;
int main()
{
memset(ans.a,0,sizeof ans.a);
ans.l=0;
scanf("%d%d",&k,&w);
for (int i=0;i<=520;++i)
{
memset(c[i][0].a,0,sizeof c[i][0].a);
c[i][0].l=1; c[i][0].a[1]=1;
}
for (int i=1;i<=520;++i)
for (int j=1;j<=520;++j)
c[i][j]=c[i-1][j]+c[i-1][j-1];
star=1<<(w%k);
big=1<<k;
// printf("%d %d %d %d\n",w%k,w/k,star,big);
for (int i=1;i<star&&w/k+i<big;++i) ans=ans+c[big-i-1][w/k];
for (int i=2;i<=w/k&&i<big;++i) ans=ans+c[big-1][i];
print(ans);
}