• 【HDU 3483】 A Very Simple Problem (二项式展开+矩阵加速)


    A Very Simple Problem

    Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
    Total Submission(s): 1022    Accepted Submission(s): 500


    Problem Description
    This is a very simple problem. Given three integers N, x, and M, your task is to calculate out the following value:

    Input
    There are several test cases. For each case, there is a line with three integers N, x, and M, where 1 ≤ N, M ≤ 2*109, and 1 ≤ x ≤ 50.
    The input ends up with three negative numbers, which should not be processed as a case.
    Output
    For each test case, print a line with an integer indicating the result.
    Sample Input
    100 1 10000
    3 4 1000
    -1 -1 -1
    Sample Output
    5050
    444
    Source

    【分析】

      感觉我的思想离正解还是太远太远,根本不会这样想。

      首先我们发现x很小,k很大,k达到了10^9,for一遍都不行,这样我们就想到ans可能存在递推式,然后可以用矩阵加速。

      

    转自:http://972169909-qq-com.iteye.com/blog/1863402

      太厉害了,我自己都好难再推一次~~

    代码如下:

     1 #include<cstdio>
     2 #include<cstdlib>
     3 #include<cstring>
     4 #include<iostream>
     5 #include<algorithm>
     6 #include<queue>
     7 #include<cmath>
     8 using namespace std;
     9 #define Maxn 60
    10 #define LL long long
    11 
    12 LL c[Maxn][Maxn];
    13 LL n,x,M;
    14 
    15 struct node
    16 {
    17     LL a[Maxn][Maxn];
    18 }t[5];
    19 
    20 void init()
    21 {
    22     memset(c,0,sizeof(c));
    23     for(LL i=0;i<=50;i++) c[i][0]=1;
    24     for(LL i=1;i<=50;i++)
    25      for(LL j=1;j<=50;j++)
    26          c[i][j]=(c[i-1][j-1]+c[i-1][j])%M;
    27 }
    28 
    29 void get_un()
    30 {
    31     memset(t[1].a,0,sizeof(t[1].a));
    32     for(LL i=0;i<=x+1;i++) t[1].a[i][i]=1%M;
    33 }
    34 
    35 void mul(LL now,LL y,LL z)
    36 {
    37     for(int i=0;i<=x+1;i++)
    38      for(int j=0;j<=x+1;j++)
    39      {
    40          t[2].a[i][j]=0;
    41          for(LL k=0;k<=x+1;k++)
    42           t[2].a[i][j]=(t[2].a[i][j]+t[y].a[i][k]*t[z].a[k][j])%M;
    43      }
    44     t[now]=t[2];
    45 }
    46 
    47 void qpow(LL b)
    48 {
    49     get_un();
    50     while(b)
    51     {
    52         if(b&1) mul(1,0,1);
    53         mul(0,0,0);
    54         b>>=1;
    55     }
    56 }
    57 
    58 int main()
    59 {
    60     while(1)
    61     {
    62         scanf("%lld%lld%lld",&n,&x,&M);
    63         if(n==-1&&x==-1&&M==-1) break;
    64         init();
    65         for(LL i=0;i<=x;i++)
    66         {
    67             for(LL j=0;j<=i;j++) t[0].a[i][j]=(x*c[i][j])%M;
    68             for(LL j=i+1;j<=x+1;j++) t[0].a[i][j]=0;
    69         }
    70         for(LL i=0;i<x;i++) t[0].a[x+1][i]=0;
    71         t[0].a[x+1][x]=t[0].a[x+1][x+1]=1%M;
    72         // get_un();
    73         qpow(n+1);
    74         printf("%lld
    ",t[1].a[x+1][0]);
    75     }
    76     return 0;
    77 }
    [HDU 3483]

    2016-09-25 22:07:05

  • 相关阅读:
    POI使用详解
    POI导入导出Excel文件(二)
    jsp页面String转JSON
    jQuery的9中构造函数
    元素的BFC特性与自适应布局
    JS replace可以接受回调函数
    基于clip-path的任意元素的碎片拼接动效(源自鑫空间)
    解耦应用逻辑/事件处理程序
    CSS行高line-height的一些深入理解及应用
    常见的三种三栏网页宽度自适应布局 方法
  • 原文地址:https://www.cnblogs.com/Konjakmoyu/p/5907143.html
Copyright © 2020-2023  润新知