zoukankan      html  css  js  c++  java
  • bzoj 2326: [HNOI2011]数学作业【dp+矩阵快速幂】

    矩阵乘法一般不满足交换律!!所以快速幂里需要注意乘的顺序!!
    其实不难,设f[i]为i的答案,那么f[i]=(f[i-1]*w[i]+i)%mod,w[i]是1e(i的位数),这个很容易写成矩阵的形式,然后按每一位分别矩阵快速幂即可
    矩阵:
    f[i-1] w[i] 1 1 f[i]
    i-1 * 0 1 1 = i
    1 0 0 1 1

    #include<iostream>
    #include<cstdio>
    using namespace std;
    long long n,mod,t;
    long long mul(long long a,long long b)
    {
    	long long r=0;
    	while(b)
    	{
    		if(b&1)
    			r=(r+a)%mod;
    		a=(a<<1)%mod;
    		b>>=1;
    	}
    	return r;
    }
    struct qwe
    {
    	long long a[5][5];
    	qwe operator * (const qwe &b) const
    	{
    		qwe c;
    		for(int i=1;i<=3;i++)
    			for(int j=1;j<=3;j++)
    			{
    				c.a[i][j]=0;
    				for(int k=1;k<=3;k++)
    					c.a[i][j]=(c.a[i][j]+mul(a[i][k],b.a[k][j]))%mod;
    			}
    		return c;
    	}
    }r;
    void wk(long long t,long long la)
    {
    	long long b=la-t/10+1;//cerr<<b<<endl;
    	qwe a;
    	a.a[1][1]=t,a.a[1][2]=1,a.a[1][3]=1;
    	a.a[2][1]=0,a.a[2][2]=1,a.a[2][3]=1;
    	a.a[3][1]=0,a.a[3][2]=0,a.a[3][3]=1;
    	while(b)
    	{
    		if(b&1)
    			r=a*r;
    		a=a*a;
    		b>>=1;
    	}
    }
    int main()
    {
    	scanf("%lld%lld",&n,&mod);
    	r.a[1][1]=r.a[2][2]=r.a[3][3]=1;
    	for(t=10;t<=n;)
    		wk(t,t-1),t*=10ll;
    	wk(t,n);
    	printf("%lld
    ",r.a[1][3]);
    	return 0;
    }
    
  • 相关阅读:
    PythonStudy——格式化输入小练习
    PythonStudy——运算符优先级 Operator precedence
    PythonStudy——逻辑运算符 Logical Operators
    ExtJS动态创建组件
    常见报表的JS代码
    sqlserver学习
    读写分离与锁分离
    oracle链接原理
    读java并发编程笔记
    日志机制在编程中的作用
  • 原文地址:https://www.cnblogs.com/lokiii/p/9605752.html
Copyright © 2011-2022 走看看