zoukankan      html  css  js  c++  java
  • JZOJ 1351. 阅读程序写结果

    题目

    Description

      NOIP2009普及组初赛阅读程序第三题如下:
      const c = 2009; 
      var 
       n, p, s, i, j, t: integer; 
      begin 
       read(n, p); 
       s := 0; 
       t := 1; 
       for i := 1 to n do 
       begin 
       t := t * p mod c; 
       for j := 1 to i do 
       s := (s + t) mod c; 
       end; 
       writeln(s); 
      end. 
      输入:11 2
      输出:______
      这题很简单,死做都能做出来,但如果扩大N的范围,你还能做吗?
     

    Input

      输入N(1<=N<=10^1000),P(1<=P<=1000),之间用一个空格隔开。

    Output

      输出结果。
     

    Sample Input

    11 2

    Sample Output

    782
     

    Data Constraint

     
     

    Hint

    【数据规模】
      50%的N<=1,000,000

     

    分析

     

    • 首先我们可以知道
    • $sum_{i=1}^{n}qquad q^i*q $这个就是我们要求的
    • 直接算有50
    • 我们考虑用矩阵快速幂优化
    • 设矩阵为$[p^i,p^i*i,sum[i-1]]$
    • 我们推得$p^(i+1)*(i+1)=p^i*p+p^i*p
    • 我们列出矩阵
    • | p  p  0 |
    • | 0  p  1 |
    • | 0  0  1 |
    • 乘出来就好了
    • 因为只有一行
    • 每一次都乘一列加起来

     

    代码

     

    #include <cmath>
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #define ll long long
    const int mo = 2009;
    using namespace std;
    int h[1020],cnt;
    struct sb
    {
        int a[3][3];
    };
    sb x;
    int ans[3];
    bool check()
    {
        for (int i=1;i<=1000;i++)
          if (h[i]!=0) return false;
        return true;
    }
    sb mul(sb x,sb y)
    {
        sb res;
        memset(res.a,0,sizeof(res));
        for (int i=0;i<3;i++)
          for (int j=0;j<3;j++)
            for (int k=0;k<3;k++)
             res.a[i][j]=(res.a[i][j]+x.a[i][k]*y.a[k][j])%mo;
        return res;
    }
    void mull() 
    {
        ll c[3];memset(c,0,sizeof(c));
        for(ll i=0;i<=2;i++)for(ll j=0;j<=2;j++)c[i]=(c[i]+x.a[j][i]*ans[j]%mo)%mo;
        for (int i=0;i<=2;i++) ans[i]=c[i];
    }
    void div()
    {
        int wz=1;
        while (h[wz]==0) wz++;
        int r=0,t;
        for (int i=wz;i<=cnt;i++)
        {
            t=h[i];
            h[i]=(r*10+h[i])/2;
            r=(r*10+t)%2;
        }
    }
    int main()
    {
        char c;
        c=getchar();
        while (c!=' ')
        {
            h[++cnt]=c-'0';
            c=getchar();
        }
        int p;
        cin>>p; 
        memset(x.a,0,sizeof(x));
        ans[0]=ans[1]=p;
        x.a[0][0]=p; x.a[0][1]=p; x.a[1][1]=p; x.a[1][2]=1; x.a[2][2]=1;
        while (!check())
        {
            if (h[cnt]&1!=0) mull();
            x=mul(x,x);
            div();
        }
        cout<<ans[2];
        return 0;
    }

     

  • 相关阅读:
    ActionScript简单实现Socket Tcp应用协议分析器
    您还有心跳吗?超时机制分析
    Java线程池架构2-多线程调度器
    Java 连接池的工作原理
    Integrating JDBC with Hibernate
    Codeforce 1255 Round #601 (Div. 2) C. League of Leesins (大模拟)
    Codeforce 1255 Round #601 (Div. 2)B. Fridge Lockers(思维)
    Codeforce 1255 Round #601 (Div. 2) A. Changing Volume (贪心)
    图论--拓扑排序--判断是否为DAG图
    图论--拓扑排序--判断一个图能否被拓扑排序
  • 原文地址:https://www.cnblogs.com/zjzjzj/p/11805344.html
Copyright © 2011-2022 走看看