题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=2326

题意:定义Concatenate(1,N)=1234567……n。比如Concatenate(1,10)=12345678910。给定n和m,求Concatenate(1,n)%m。

思路:令f[n]表示Concatenate(1,n)。那么有:

f[i]=f[i-1]*10+(i-1)+1   1<=i<=9

f[i]=f[i-1]*100+(i-1)+1  10<=i<=99

……

因此可用矩阵加速:

但是,这个矩阵是分段的。

#include <iostream>
#include <cstdio>
#include <string.h>
#include <algorithm>
#include <cmath>
#include <vector>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <map>

#define max(x,y) ((x)>(y)?(x):(y))
#define min(x,y) ((x)<(y)?(x):(y))
#define abs(x) ((x)>=0?(x):-(x))
#define i64 long long
#define u32 unsigned int
#define u64 unsigned long long
#define clr(x,y) memset(x,y,sizeof(x))
#define CLR(x) x.clear()
#define ph(x) push(x)
#define pb(x) push_back(x)
#define Len(x) x.length()
#define SZ(x) x.size()
#define PI acos(-1.0)
#define sqr(x) ((x)*(x))
#define MP(x,y) make_pair(x,y)
#define EPS 1e-10

#define FOR0(i,x) for(i=0;i<x;i++)
#define FOR1(i,x) for(i=1;i<=x;i++)
#define FOR(i,a,b) for(i=a;i<=b;i++)
#define FORL0(i,a) for(i=a;i>=0;i--)
#define FORL1(i,a) for(i=a;i>=1;i--)
#define FORL(i,a,b)for(i=a;i>=b;i--)

#define rush() int CC;for(scanf("%d",&CC);CC--;)
#define Rush(n)  while(scanf("%d",&n)!=-1)
using namespace std;

void RD(int &x){scanf("%d",&x);}
void RD(i64 &x){scanf("%lld",&x);}
void RD(u64 &x){scanf("%I64u",&x);}
void RD(u32 &x){scanf("%u",&x);}
void RD(double &x){scanf("%lf",&x);}
void RD(int &x,int &y){scanf("%d%d",&x,&y);}
void RD(i64 &x,i64 &y){scanf("%lld%lld",&x,&y);}
void RD(u32 &x,u32 &y){scanf("%u%u",&x,&y);}
void RD(double &x,double &y){scanf("%lf%lf",&x,&y);}
void RD(int &x,int &y,int &z){scanf("%d%d%d",&x,&y,&z);}
void RD(i64 &x,i64 &y,i64 &z){scanf("%lld%lld%lld",&x,&y,&z);}
void RD(u32 &x,u32 &y,u32 &z){scanf("%u%u%u",&x,&y,&z);}
void RD(double &x,double &y,double &z){scanf("%lf%lf%lf",&x,&y,&z);}
void RD(char &x){x=getchar();}
void RD(char *s){scanf("%s",s);}
void RD(string &s){cin>>s;}

void PR(int x) {printf("%d\n",x);}
void PR(int x,int y) {printf("%d %d\n",x,y);}
void PR(i64 x) {printf("%lld\n",x);}
void PR(u32 x) {printf("%u\n",x);}
void PR(u64 x) {printf("%llu\n",x);}
void PR(double x) {printf("%.2lf\n",x);}
void PR(char x) {printf("%c\n",x);}
void PR(char *x) {printf("%s\n",x);}
void PR(string x) {cout<<x<<endl;}

const int mod=10007;
const i64 inf=((i64)1)<<60;
const double dinf=1000000000000000000.0;
const int INF=1000000005;
const int N=405;

i64 n,m;

struct Matrix
{
    i64 a[3][3];

void init(int x)
    {
        clr(a,0);
        if(x==1) a[0][0]=a[1][1]=a[2][2]=1;
    }

Matrix operator*(Matrix p)
    {
        Matrix ans;
        ans.init(0);
        int i,j,k;
        FOR0(k,3) FOR0(i,3) FOR0(j,3)
        {
            ans.a[i][j]+=a[i][k]*p.a[k][j]%m;
            ans.a[i][j]%=m;
        }
        return ans;
    }

Matrix power(i64 n)
    {
        Matrix ans,p=*this;
        ans.init(1);
        while(n)
        {
            if(n&1) ans=ans*p;
            p=p*p;
            n>>=1;
        }
        return ans;
    }
};

i64 p[20];

void init()
{
    int i;
    p[0]=1;
    for(i=1;i<=18;i++) p[i]=p[i-1]*10;
}

Matrix cal(i64 n,i64 k)
{
    Matrix a;
    a.init(0);
    a.a[0][0]=k;
    a.a[1][0]=a.a[1][1]=a.a[2][0]=a.a[2][1]=a.a[2][2]=1;
    return a.power(n);
}

int main()
{
    RD(n,m); init(); Matrix b; b.init(1);
    i64 i,L,R;
    for(i=1;;i++)
    {
        L=p[i-1];
        R=min(p[i]-1,n);
        b=b*cal(R-L+1,p[i]%m);
        if(R==n) break;
    }
    PR(b.a[2][0]);
}

BZOJ 2326 数学作业(矩阵)的更多相关文章

  1. BZOJ 2326 数学作业(分段矩阵快速幂)

    实际上,对于位数相同的连续段,可以用矩阵快速幂求出最后的ans,那么题目中一共只有18个连续段. 分段矩阵快速幂即可. #include<cstdio> #include<iostr ...

  2. CJOJ 1331 【HNOI2011】数学作业 / Luogu 3216 【HNOI2011】数学作业 / HYSBZ 2326 数学作业(递推,矩阵)

    CJOJ 1331 [HNOI2011]数学作业 / Luogu 3216 [HNOI2011]数学作业 / HYSBZ 2326 数学作业(递推,矩阵) Description 小 C 数学成绩优异 ...

  3. BZOJ 2326: [HNOI2011]数学作业( 矩阵快速幂 )

    BZOJ先剧透了是矩阵乘法...这道题显然可以f(x) = f(x-1)*10t+x ,其中t表示x有多少位. 这个递推式可以变成这样的矩阵...(不会用公式编辑器...), 我们把位数相同的一起处理 ...

  4. BZOJ-2326 数学作业 矩阵乘法快速幂+快速乘

    2326: [HNOI2011]数学作业 Time Limit: 10 Sec Memory Limit: 128 MB Submit: 1564 Solved: 910 [Submit][Statu ...

  5. [HNOI2011]数学作业 --- 矩阵优化

    [HNOI2011]数学作业 题目描述: 小 C 数学成绩优异,于是老师给小 C 留了一道非常难的数学作业题: 给定正整数 N 和 M ,要求计算\(Concatenate(1..N)\; Mod\; ...

  6. 洛谷P3216 [HNOI2011] 数学作业 [矩阵加速,数论]

    题目传送门 数学作业 题目描述 小 C 数学成绩优异,于是老师给小 C 留了一道非常难的数学作业题: 给定正整数 N和 M,要求计算 Concatenate (1 .. N)Mod M 的值,其中 C ...

  7. 【BZOJ2326】【HNOI2011】数学作业 [矩阵乘法][DP]

    数学作业 Time Limit: 10 Sec  Memory Limit: 128 MB[Submit][Status][Discuss] Description Input 输入文件只有一行为用空 ...

  8. [HNOI2011]数学作业 矩阵快速幂 BZOJ 2326

    题目描述 小 C 数学成绩优异,于是老师给小 C 留了一道非常难的数学作业题: 给定正整数 NNN 和 MMM ,要求计算Concatenate(1..N) Concatenate (1 .. N) ...

  9. BZOJ 2326: [HNOI2011]数学作业(矩阵乘法)

    传送门 解题思路 NOIp前看到的一道题,当时想了很久没想出来,NOIp后拿出来看竟然想出来了.注意到有递推\(f[i]=f[i-1]*poww[i]+i\),\(f[i]\)表示\(1-i\)连接起 ...

随机推荐

  1. Linux C 文件与目录1 创建目录

    linux C    创建目录 创建目录函数:mkdir 函数原型:int mkdir(char * pathname , mode_t mode); pathname字符指针是表示需要创建的目录路径 ...

  2. 常用的机器学习&数据挖掘知识点【转】

    转自: [基础]常用的机器学习&数据挖掘知识点 Basis(基础): MSE(Mean Square Error 均方误差),LMS(LeastMean Square 最小均方),LSM(Le ...

  3. C#开源大全--汇总

    商业协作和项目管理平台-TeamLab 网络视频会议软件-VMukti 驰骋工作流程引擎-ccflow [免费]正则表达式测试工具-Regex-Tester Windows-Phone-7-SDK E ...

  4. ADO.NET- 基础总结及实例介绍

    最近闲暇时间写的一些小程序中,访问数据库比较多:下面主要介绍下ADO.NET方面知识,有不足之处,希望大神们不吝赐教: 提到ADO.NET,经常会和ASP.NET进行混淆,两者的区别很大,没有可比性, ...

  5. MyEclipse2015破解版_MyEclipse 2015 stable 2.0 稳定版 破解日志

    前言:在MyEclipse 2015 Stable 1.0下载安装破解日志(http://www.cnblogs.com/wql025/p/5161979.html)一文中,笔者主要讲述了该版本的破解 ...

  6. 【BZOJ】【1051】【HAOI2005】受欢迎的牛

    按B->A连边,tarjan缩点,然后找入度为0的连通分量,如果有1个,则ans=size[i],如果大于一个则ans=0: 当然如果按A->B连边就是找出度为0的(表示没有被它喜欢的,这 ...

  7. PHP之Error与Logging函数讲解

    PHP Error 和 Logging 简介 error 和 logging 函数允许你对错误进行处理和记录. error 函数允许用户定义错误处理规则,并修改记录错误的方式. logging 函数允 ...

  8. jquery mouseout事件冒泡解决方法

    在界面中最多使用的是div,如果一个div中包含多个div或img对象时, 针对mouseout鼠标移出事件时,并没有移出div层,但是当移动到div中的img时,也触发了该mouseout事件,这就 ...

  9. 【C++基础】 类中static private public protected

    静态成员在一个类的所有实例间共享数据 “类属性”,是描述类的所有对象共同特征的一个数据项,对所有对象,它的值相同,static定义,为整个类所共有.相对于“实例属性” 如果static成员是私有类型, ...

  10. java生成二维码的三个工具

    1.  使用SwetakeQRCode在Java项目中生成二维码 http://swetake.com/qr/ 下载地址 或着http://sourceforge.jp/projects/qrcode ...