zoukankan      html  css  js  c++  java
  • TOJ4277: Sequence 组合数学

    4277: Sequence 

    Time Limit(Common/Java):2000MS/6000MS     Memory Limit:65536KByte
    Total Submit: 39            Accepted:11

    Description

    YXH is very fond of the sequence. One day he found a very interesting sequence.
    At time T, a sequence A is
    A(1),A(2),...,A(n)
    After one second (at time T + 1), the sequence will become
    A(1),A(2)+2A(1),A(3)+2A(2)+3A(1),…,A(n)+2A(n-1)+...+nA(1)
    YXH wants to know the sequence at time K. Can you solve this problem?

    Input

    There are multiple test cases.
    For each case, the first line contains a number N indicating the length of the sequence. The second line contains N numbers indicating the sequence in time 0. The third line contains a number K as description above.

    1 <= N <= 300, 1 <= K <= 1,000,000,000
    The value of each number in the sequence will not exceed 300.

    Output

    For each case, print the sequence at time K in one line. Since the answer could be very large, you should output the answer module 1,000,000,007

    Sample Input

    Sample Output

    Source

    2012年武汉大学第六届E鸣杯程序设计竞赛

    看似矩阵快速幂,但是这个矩阵是300*300的矩阵,很容易就爆炸了,因为矩阵乘法是n^3的,再做快速幂是logk

    这个矩阵的构造应该不算是很难吧,就是填1到n,然后斜线上的值是一样的

    矩阵快速幂代码

     

    #include<stdio.h>
    #include<bits/stdc++.h>
    using namespace std;
    const int N=305,MD=1e9+7,INF=0x3f3f3f3f;
    const double eps=1e-9,e=exp(1),PI=acos(-1.);
    typedef long long ll;
    int G;
    struct MX
    {
        int v[N][N];
        void O()
        {
            memset(v,0,sizeof v);
        }
        void E()
        {
            memset(v,0,sizeof v);
            for(int i=0; i<G; i++)
                for(int j=i;j<G;j++)v[i][j]=j-i+1;
        }
        void P()
        {
            for(int i=0; i<G; i++)
                for(int j=0; j<G; j++)printf(j==G-1?"%d
    ":"%d ",v[i][j]);
        }
        MX operator+(const MX &b) const
        {
            MX c;
            c.O();
            for(int i=0; i<G; i++)
                for(int j=0; j<G; j++)c.v[i][j]=v[i][j]+b.v[i][j];
            return c;
        }
        MX operator*(const MX &b)const
        {
            MX c;
            c.O();
            for(int k=0; k<G; k++)
                for(int i=0; i<G; i++)
                    if(v[i][k])for(int j=0; j<G; j++)c.v[i][j]=(c.v[i][j]+1LL*v[i][k]*b.v[k][j]%MD)%MD;
            return c;
        }
         MX operator^(int p)const
        {
            MX y,x;
            y.E(),memcpy(x.v,v,sizeof(v));
            for(; p; x=x*x,p>>=1)if(p&1)y=y*x;
            return y;
        }
    } a,ans;
    int main()
    {
        //ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
        int n,k;
        while(~scanf("%d",&n))
        {
            G=n;
            a.O();
            for(int i=0; i<n; i++)scanf("%d",&a.v[0][i]);
            scanf("%d",&k);
            ans.E();
            ans=ans^(k-1);
            ans=a*ans;
            for(int i=0; i<n; i++)printf(i==G-1?"%d
    ":"%d ",ans.v[0][i]);
        }
        return 0;
    }

     

    接下来进入找规律环节,找个p的规律啊。

    因为我比较傻,还以为这个还是和快速幂的拼凑有关的,就只去了打了2 4  16 256的值,很难发现规律

    然后我每个都打了一次

    k=0显而易见 1 2 3 4 5 6

    k=1  1 2 ...  

    k=2  1 4 ...

    反正你很快会发现就是这一项是C(i,2k-1+i)

    所以你很想到组合数

    但是直接求组合数可行么,是可行的,当然k很大,你不会玩

    其实就是乘上新加的数,除以i,当然这个题目要除以逆元

    #include<stdio.h>
    const int N=305,MD=1e9+7;
    int a[N],b[N],v[N],n,k,i,j;
    int main()
    {
        v[1]=b[0]=1;
        for(int i=2;i<N;i++)v[i]=1LL*v[MD%i]*(MD-MD/i)%MD;
        while(scanf("%d",&n)!=EOF)
        {
            for(i=0; i<n; i++)scanf("%d",&a[i]);
            scanf("%d",&k);
            long long t=2*k;
            for(i=1; i<n; i++,t++)b[i]=t*b[i-1]%MD*v[i]%MD;
            for(i=n-1; i>0; i--)
                for(j=1; j<=i; j++)a[i]=(a[i]+b[j]*1LL*a[i-j])%MD;
            for(i=0; i<n; i++)printf(i==n-1?"%d
    ":"%d ",a[i]);
        }
        return 0;
    }

     

  • 相关阅读:
    冲刺阶段个人博客9
    冲刺阶段个人博客8
    梦断代码阅读笔记02
    我关于搜狗输入法的用户体验描述
    冲刺阶段个人博客07
    冲刺阶段个人博客06
    冲刺阶段个人博客05
    冲刺阶段个人博客04
    BZOJ 2006 超级钢琴(堆+主席树)
    BZOJ 1924 所驼门王的宝藏(强连通分量缩点+DAG最长链)
  • 原文地址:https://www.cnblogs.com/BobHuang/p/9449560.html
Copyright © 2011-2022 走看看