zoukankan      html  css  js  c++  java
  • CF 717A Festival Organization——斯特林数+递推求通项+扩域

    题目:http://codeforces.com/contest/717/problem/A

    是 BJOI2019 勘破神机 的弱化版。

    令 ( g[i] ) 表示长为 i 、以 1 结尾的方案数,有 ( g[i]=g[i-1]+g[i-2] , g[0]=g[1]=1 ) ;

    令 ( f[i] ) 表示长为 i 的方案数,有 ( f[i]=g[i]+g[i-1] )

    发现 ( f[i]=f[i-1]+f[i-2] , f[0]=1 , f[1]=2 )

    那么令 l+=2 , r+=2 , f[ i ] 就是普通的斐波那契数。用 BJOI 那道题的套路即可。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define ll long long
    using namespace std;
    const int N=205,mod=1e9+7;
    int upt(int x){while(x>=mod)x-=mod;while(x<0)x+=mod;return x;}
    int pw(int x,int k)
    {int ret=1;while(k){if(k&1)ret=(ll)ret*x%mod;x=(ll)x*x%mod;k>>=1;}return ret;}
    
    int k,s[N][N],c[N][N],ans;
    int tlen;ll l,r,len;
    struct Node{
      int x,y;
      Node(int x=0,int y=0):x(x),y(y) {}
      Node operator+ (const Node &b)const
      {return Node(upt(x+b.x),upt(y+b.y));}
      Node operator- (const Node &b)const
      {return Node(upt(x-b.x),upt(y-b.y));}
      Node operator* (const Node &b)const
      {return Node(((ll)x*b.x+(ll)y*b.y%mod*5)%mod,((ll)x*b.y+(ll)y*b.x)%mod);}
    }A[N],B[N],x1[N],x2[N],one;
    Node pw(Node x,ll k)
    {Node ret=one;while(k){if(k&1)ret=ret*x;x=x*x;k>>=1;}return ret;}
    void init()
    {
      s[0][0]=1;
      for(int i=1;i<=k;i++)
        for(int j=1;j<=i;j++)
          s[i][j]=(s[i-1][j-1]+(ll)s[i-1][j]*(i-1))%mod;
      for(int i=0;i<=k;i++)c[i][0]=1;
      for(int i=1;i<=k;i++)
        for(int j=1;j<=i;j++)
          c[i][j]=upt(c[i-1][j-1]+c[i-1][j]);
    
      one=Node(1,0); int tp=pw(5,mod-2);
      A[1]=Node(0,tp); B[1]=Node(0,upt(-tp));
      tp=pw(2,mod-2); x1[1]=Node(tp,tp); x2[1]=Node(tp,upt(-tp));
      A[0]=B[0]=x1[0]=x2[0]=one;
      for(int i=2;i<=k;i++)A[i]=A[i-1]*A[1];
      for(int i=2;i<=k;i++)B[i]=B[i-1]*B[1];
      for(int i=2;i<=k;i++)x1[i]=x1[i-1]*x1[1];
      for(int i=2;i<=k;i++)x2[i]=x2[i-1]*x2[1];
    }
    Node Inv(Node x)
    {
      int tp=upt(((ll)x.x*x.x-(ll)x.y*x.y%mod*5)%mod);
      tp=pw(tp,mod-2);
      return Node((ll)x.x*tp%mod,upt(-(ll)x.y*tp%mod));
    }
    Node cal(Node x)
    {
      if(x.x==1&&x.y==0)return Node(tlen,0);
      return pw(x,l)*(one-pw(x,len))*Inv(one-x);
    }
    int main()
    {
      scanf("%d%lld%lld",&k,&l,&r); l+=2; r+=2;
      init(); len=r-l+1; tlen=len%mod;
      for(int j=0,fx=((k&1)?upt(-1):1);j<=k;j++,fx=upt(-fx))
        {
          int tp=0;
          for(int t=0;t<=j;t++)
        {
          Node d=cal(x1[t]*x2[j-t]);
          d=d*A[t]*B[j-t];
          tp=(tp+(ll)c[j][t]*d.x)%mod;
        }
          ans=(ans+(ll)s[k][j]*fx%mod*tp)%mod;
        }
      int ml=1;
      for(int i=2;i<=k;i++)ml=(ll)ml*i%mod;
      ml=pw(ml,mod-2);
      ans=(ll)ans*ml%mod;
      printf("%d
    ",ans);
      return 0;
    }
  • 相关阅读:
    需求分析与系统设计(二)阅读笔记
    阅读笔记:需求分析与系统设计(一)
    css方法div固定在网页底部
    阅读笔记:软件需求十步走(三)
    剑指offer 二维数组中的查找
    剑指offer 替换空格
    剑指offer 重建二叉树
    git常用操作
    关于 IO的同步异步间要描述
    svn-代码回滚
  • 原文地址:https://www.cnblogs.com/Narh/p/10946652.html
Copyright © 2011-2022 走看看