codeforces #307 D. GukiZ and Binary Operations(各种快速幂+斐波那契)
来源:互联网 发布:linux tomcat 改端口 编辑:程序博客网 时间:2024/05/16 19:25
题目链接:
罪恶的链接
题目大意:
有一个数组,(a1&&a2)|| ....... (an-1&&an)=k,ai<=2^l,求取这样的数组的数量%m
题目分析:
作为一个弱渣,这道题调了一上午才过,简直了。。。。
其实思路很简单,首先将k化为二进制数,那么如果k的某一个二进制位是0,那么也就是这个数组的相邻数位不可能全是1
因此我们得到如下的递推式:dp[i] = dp[i-1]+dp[i-2],当第i位放0时,那么有dp[i-1]中情况,如果第i位放1,那么第i-1位必须放0,所以有dp[i-2]种情况,正好可以看出是斐波那契数列,那么我们可以通过矩阵快速幂快速求取
然后看为1的情况,dp[i] = 2^n-1 + dp[i-1] ,表示当前两个数位都是1,那么其他的随便放,也就是2^n-1,如果当前两个数位不全是1,那么前面必有一个是1,所以是dp[i-1]种,但是这么做的话,递推起来又过于麻烦,可以突然想到只有1,0两种情况,一共的情况数是2^n,那么减掉0的情况不就是1的情况了吗!!!!被自己蠢哭了。。。
#include <iostream>#include <cstring>#include <cstdio>#include <algorithm>#include <vector>#define MAX 2using namespace std;typedef long long LL;LL m,n,l,k;struct Matrix { LL a[MAX][MAX];};void reset ( Matrix& m ){ memset ( m.a , 0 , sizeof ( m.a ) );}void set ( Matrix& m ){ memset ( m.a , 0 , sizeof ( m.a ) ); for ( int i = 0 ; i < 2 ; i++ ) m.a[i][i] = 1;}Matrix multi ( Matrix m1 , Matrix m2 ){ Matrix ret; reset ( ret ); for ( int i = 0 ; i < 2 ; i++ ) for ( int j = 0 ; j < 2 ; j++ ) if ( m1.a[i][j] ) for ( int k = 0 ; k < 2 ; k++ ) ret.a[i][k] = (ret.a[i][k] + m1.a[i][j] * m2.a[j][k]%m)%m; return ret;}Matrix quickMulti ( Matrix m1 , LL n ){ Matrix ret; set ( ret ); while ( n ) { if ( n&1 ) ret = multi ( ret , m1 ); m1 = multi ( m1 , m1 ); n >>= 1; } return ret;}LL pow ( LL x , LL n ){ LL ret = 1; while ( n ) { if ( n&1 ) ret = ret*x%m; x = x*x%m; n >>= 1; } return ret;}Matrix a,b;LL ans;void init ( ){ reset ( b ); b.a[0][0] = b.a[0][1] = b.a[1][0] = 1; ans = 1;}int main ( ){ while ( cin >> n >> k >> l >> m ) { init(); b = quickMulti ( b , n+1 ); LL k1 = b.a[0][0]; LL k2 = ((pow (2,n)-k1)%m+m)%m; int cnt = 0; if ( m == 1 ) { puts ("0"); continue; } if ( l < 63 && (1LL<<l) <= k ) { puts ( "0" ); continue; } if ( l == 0 ) { if ( k == 0 ) puts("1"); else puts("0"); continue; } while ( k ) { if ( k&1 ) ans = ans*k2%m; else ans = ans*k1%m; k >>= 1; cnt++; } while ( cnt++ < l ) ans = ans*k1%m; ans = (ans%m+m)%m; cout << ans << endl; }}
0 0
- codeforces #307 D. GukiZ and Binary Operations(各种快速幂+斐波那契)
- cf#307-D. GukiZ and Binary Operations-矩阵快速幂
- Codeforces Round #307 (Div. 2) D. GukiZ and Binary Operations (矩阵快速幂)
- Codeforces Round #307 (Div. 2) 551D - GukiZ and Binary Operations 矩阵快速幂
- Codeforces 551D GukiZ and Binary Operations
- Codeforces 551 D. GukiZ and Binary Operations
- codeforces 551 D. GukiZ and Binary Operations
- CodeForces 551 D.GukiZ and Binary Operations(dp+矩阵快速幂)
- Codeforces Round #307 (Div. 2)--C. GukiZ hates Boxes、D. GukiZ and Binary Operations
- CodeForces 551D GukiZ and Binary Operations DP+矩阵乘法
- Codeforces Round #307 (Div. 2) D. GukiZ and Binary Operations(数学)
- CF 551D GukiZ and Binary Operations
- GukiZ and Binary Operations(矩阵+二进制)
- CF551D:GukiZ and Binary Operations(矩阵 & 思维)
- Codeforces D. Professor GukiZ and Two Arrays
- codeforces #307 E. GukiZ and GukiZiana(分块+二分查找)
- Educational Codeforces Round 6 D. Professor GukiZ and Two Arrays
- CodeForces 620D Professor GukiZ and Two Arrays
- 第十四周 【项目2-用文件保存的学生名单】若干名学生的学号 姓名和C++课、高数和英语成绩
- ava集合类详解
- 第14周项目2-用文件保存的学生名单
- Java中如何处理空指针异常
- #9 Palindrome Number
- codeforces #307 D. GukiZ and Binary Operations(各种快速幂+斐波那契)
- 树状数组(二维)例题 HDU2642——Stars
- C#高级编程十七天----Object类
- 第14周项目3-OOP版电子词典
- PLC输出的三种方式
- 接口 Map<K,V>
- 第14周项目4-处理C++源代码的程序
- 会做的,不如会说的
- 日语学习之沪江N3基础 20150621 -5