汤汤的女装
作者:互联网
众所周知,16级的竞赛带头人汤汤是个女装爱好者,经常cosplay成玩家喜闻乐见的女性角色出现在动漫展上,因为其妖娆的身姿、魅惑的神情,经常能够博得全场好评,那些看客无不发出awsl、我又好了之类的惊呼。16级的学习の光——郑一花一直很想得到汤汤的女装珍藏,可惜汤汤视若珍宝,说什么也不肯。终于在一个月黑风高的白天,一花设计给汤汤吃狗粮,狗粮是给菜狗吃的,比如LJL这样的单身菜狗,汤汤只是一个平平无奇、爱好女装的现充,哪里能吃得这种东西。汤汤被毒进医院之后,他的一票后宫都跟着进去陪护了,一花乘虚而入,万万没想到要打开汤汤的女装柜需要输入相应的密码。
所幸,他抓来了正在给汤汤扫地的LJL,并承诺支付他三个月的狗粮,LJL哪里禁得住这样的诱惑。但是他也只知道密码表示的是邪恶数的个数,每个邪恶数都对应汤汤一个邪恶形态,每个邪恶数具有如下性质:
1.一共有n位,每位都是奇数。鲁迅曾经说过:奇变偶不变、符号看象限,全部都用奇数组成的密码反映的正是汤汤邪恶的本质。
2.其中3、5、7的出现次数都是偶数次,据说这个奇怪的设定是因为汤汤对于某个传奇教练发型的致敬,这边按下不表。
一花心领神会,解出密码之后将汤汤多年的积蓄席卷一空,那么他到底是怎么做到的呢。 给定邪恶数位数n,邪恶数有多少个?换言之,汤汤到底有多少种不同的邪恶形态呢?
输入格式:
每个测试点只输入一个n(1<=n<=10^18),表示邪恶数的位数。
输出格式:
输出邪恶数的个数,因为数字太大,请对10^9+7取模
输入样例1:
1
输出样例1:
2
输入样例2:
2
输出样例2:
7
提示:
如果邪恶数只有1位、满足条件的只有1和9 如果邪恶数有两位,满足条件的有33、55、77、19、91、11、99
解题思路
(1)对于i-1的所有方案,只需在最后加上5个奇数,再加以判断就可以得到第i个状态
这样也就说明要记录的不仅仅是成功的方案,还要记录加入奇数可以转移至成功方案的所有方案
(2)3,5,7各取奇偶个,总共有2^3=8种情况
其中第1种情况记录为,偶偶偶也就是bi[0]所储存的
(3)A[i][j]表示从状态i转移到状态j有几种方案
题解没有错!!!这句话很重要
第i个状态是被消去的状态,最后留下来的是j
(4)bi表示总位数为i位时,所拥有的全部方案
容易得到b1[0]=2;
状态转移矩阵:bn=b1*A^(n-1)
#include<cstdio> #include<vector> using namespace std; typedef long long ll; typedef vector<ll> vec; typedef vector<vec> mat; //简化声明一个矩阵 const ll md = 1e9 + 7; //矩阵乘法 mat mul(const mat& a, const mat& b) { mat res(a.size(), vec(b[0].size())); //初始化res,取a的行,每行有b[0].size()个 0、 //易得,行==列 //矩阵乘法 for (int i = 0; i < a.size(); ++i) { for (int k = 0; k < b.size(); ++k) { for (int j = 0; j < b[0].size(); ++j) { res[i][j] = (res[i][j] + a[i][k] * b[k][j] % md) % md; } } } return res; } //矩阵快速幂 mat Quickpow(mat a, ll n) { mat res(a.size(), vec(a.size())); //初始化一个值都为0的方阵 for (int i = 0; i < a.size(); ++i)res[i][i] = 1; //单位矩阵E while (n) { if (n & 1)res = mul(res, a); a = mul(a, a); n >>= 1; } return res; } int main() { ll n; scanf("%lld", &n); mat a = {{2, 1, 1, 0, 1, 0, 0, 0}, {1, 2, 0, 1, 0, 1, 0, 0}, {1, 0, 2, 1, 0, 0, 1, 0}, {0, 1, 1, 2, 0, 0, 0, 1}, {1, 0, 0, 0, 2, 1, 1, 0}, {0, 1, 0, 0, 1, 2, 0, 1}, {0, 0, 1, 0, 1, 0, 2, 1}, {0, 0, 0, 1, 0, 1, 1, 2} }; //求出矩阵A的n-1次方 a = Quickpow(a, n - 1); //状态转移方程矩阵bn=b1*A^(n-1) //bn[0]为所求答案,bn的第0行,乘以A的第0列 ll ans = (((2 * a[0][0] % md + a[1][0]) % md + a[2][0]) % md + a[4][0]) % md; printf("%lld", ans); }
标签:md,mat,res,汤汤,邪恶,女装,size 来源: https://www.cnblogs.com/ghostlx/p/13780128.html