bzoj 3028 食物——生成函数

题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3028

把式子写出来,化一化,变成 x / ((1-x)^4) ,变成几个 sigma 相乘的样子,用组合意义看一下第 n 项的系数,就是 n-1 的可以不选的划分,即 C( n-1+3,3 ) 。为了高精度方便,化成 (n+2)*(n+1)*n/6 。

别忘了取模。

注意读入高精度数字的方法。错了几次之后只会一位一位地读了……

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=1600,base=1e2,mod=10007;
int a[N],b[N],c[N];
void rdn()
{
  char ch=getchar();
  while(ch>'9'||ch<'0')ch=getchar();
  while(ch>='0'&&ch<='9')
    b[++b[0]]=ch-'0',ch=getchar();
  for(int i=b[0];i>1;i-=2)
    a[++a[0]]=(b[i-1]<<3)+(b[i-1]<<1)+b[i];
  if(b[0]&1)a[++a[0]]=b[1];
  for(int i=a[0]+1;i<=b[0];i++)b[i]=0;
}
void print(int *a)
{
  printf("%d",a[a[0]]);
  for(int i=a[0]-1;i;i--)
    printf("%02d",a[i]);
  puts("");
}
void pls(int *b,int x)
{
  b[1]+=x;
  for(int i=1;i<=b[0];i++)
    {
      if(b[i]<base)break;
      b[i+1]+=b[i]/base;b[i]%=base;
    }
  while(b[b[0]+1])
    {
      b[0]++;
      b[b[0]+1]+=b[b[0]]/base;b[b[0]]%=base;
    }
}
void mul()
{
  c[0]=a[0]+b[0]-1;
  for(int i=1;i<=a[0];i++)
    for(int j=1;j<=b[0];j++)
      c[i+j-1]+=a[i]*b[j];
  for(int i=1;i<=c[0];i++)
    c[i+1]+=c[i]/base,c[i]%=base;
  while(c[c[0]+1])
    {
      c[0]++;
      c[c[0]+1]+=c[c[0]]/base;c[c[0]]%=base;
    }
  for(int i=1;i<=c[0];i++)
    a[i]=c[i],c[i]=0;
  a[0]=c[0]; c[0]=0;
}
void div(int *a,int x)
{
  for(int i=a[0];i;i--)
    {
      if(i>1) a[i-1]+=(a[i]%x)*base;
      a[i]/=x;
    }
  while(a[0]>1&&!a[a[0]])a[0]--;
}
void upd(int *a)
{
  for(int i=a[0];i>1;i--)
    a[i-1]+=a[i]%mod*base;
}
int main()
{
  rdn();
  for(int i=0;i<=a[0];i++)b[i]=a[i];
  pls(b,1);mul();
  pls(b,1);mul();
  div(a,6);upd(a);
  printf("%d\n",a[1]%mod);
  return 0;
}

 

posted on 2018-11-27 19:47  Narh  阅读(147)  评论(0编辑  收藏  举报

导航