zoj - 3538(矩阵乘法)

  题目链接:here——————

  题意:有四个人 A,B,C,D 每天出一套卷子,相邻的两天不能由同一个人出题

      给你两个数n,m分别表示n天和m个操作(把第ai天定为有bi出题)

      问有多少种方式??

  题解:  先排序

        if  bi == bi-1 && ai - ai-1 = 1     return 0;

        if       bi == bi-1  设f1 = 3;fn = 3^n - fn-1;

      else    f1 = 2;fn = 3^n - fn-1;

      再判断两头

      矩阵    -1,0

          3,3

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<algorithm>
 5 using namespace std;
 6 typedef long long LL;
 7 const LL mod = 1000000007;
 8 struct Z{
 9     LL m[2][2];
10     LL a;
11     string b;
12 }s[20];
13 Z A ={
14     -1,0,
15     3,3
16 };
17 Z B = {
18     1,0,
19     0,1
20 };
21 LL Pow(LL a,LL b){
22     LL res = 1;
23     while(b){
24         if(b&1) res = res * a % mod ;
25         a = a * a % mod;
26         b >>= 1;
27     }
28     return res;
29 }
30 bool cmp(Z p,Z q){
31     return p.a < q.a;
32 }
33 Z operator * (const Z& a,const Z& b){
34     Z c;
35     for(int i = 0;i < 2 ; ++ i)
36         for(int j = 0;j < 2;j++){
37             c.m[i][j] = 0;
38             for(int k = 0;k < 2;k++)
39                 c.m[i][j] = (c.m[i][j] + a.m[i][k] * b.m[k][j]) % mod;
40         }
41     return c;
42 }
43 Z mpow(int n){
44     Z ret , p;
45     ret = B, p = A;
46     while(n){
47         if(n&1) ret = ret * p;
48         p = p * p;
49         n >>= 1;
50     }
51     return ret;
52 }
53 int main(){
54     LL n,m,flag = 0;;
55     while(cin>>n>>m){
56         if(m == 0){
57             LL x = 4 * Pow(3,n-1) % mod;
58             cout << x << endl;
59             continue;
60         }
61         for(int i = 1;i <= m;i++)
62             cin>>s[i].a>>s[i].b;
63
64         if(m == 1){
65             LL x = Pow(3,n-1);
66             cout << x << endl;
67             continue;
68         }
69         sort(s+1,s+m+1,cmp);
70         LL x = 1;
71         Z ant;
72         s[0].a = 0;
73         for(int i = 1;i <= m; ++ i){
74
75             if(s[i-1].a != 0){
76                 LL abs = s[i].a - s[i-1].a - 2;
77                 if(abs < 0)
78                 {
79                     if(s[i-1].b[0] == s[i].b[0]) {x = 0;break;}
80                     continue;
81                 }
82                 ant = mpow(abs);
83                 if(s[i-1].b[0] == s[i].b[0])
84                    x = x * (ant.m[0][0]*3 + ant.m[1][0]*3)%mod;
85                 else x = x * (ant.m[0][0]*2 + ant.m[1][0]*3)%mod;
86
87             }
88             else {
89                 x = x * Pow(3,s[i].a - 1) % mod;
90             }
91             if(i == m && s[i].a < n){
92                 x = x * Pow(3,n-s[i].a) % mod;
93             }
94         }
95         cout << (x%mod + mod)%mod<< endl;
96     }
97 }

时间: 2024-08-07 08:34:59

zoj - 3538(矩阵乘法)的相关文章

ZOJ 2671 -Cryptography ( 矩阵乘法 + 线段树 )

ZOJ 2671 - Cryptography ( 矩阵乘法 + 线段树 ) 题意: 给定模数r, 个数n, 询问数m 然后是n个矩阵,每次询问,输出矩阵联乘之后的结果. 分析: 矩阵乘法 + 线段树优化 这里线段树只有询问没有更新操作. PS:顺便仰慕一下watashi.... 代码: #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> using names

ZOJ 2671 Cryptography 矩阵乘法+线段树

B - Cryptography Time Limit:5000MS     Memory Limit:32768KB     64bit IO Format:%lld & %llu Submit Status Practice ZOJ 2671 Description Young cryptoanalyst Georgie is planning to break the new cipher invented by his friend Andie. To do this, he must

ZOJ - 3216:Compositions (DP&amp;矩阵乘法&amp;快速幂)

We consider problems concerning the number of ways in which a number can be written as a sum. If the order of the terms in the sum is taken into account the sum is called a composition and the number of compositions of n is denoted by c(n). Thus, the

zoj 3538 Arrange the Schedule

Arrange the Schedule Time Limit: 1 Second      Memory Limit: 65536 KB In Summer 2011, the ZJU-ICPC Team has a n-days training schedule. ZJU-ICPC Team has been divided into 4 Group: Akiba, BiliBili, CIA, Double(Group A, B, C, D). There is a group in c

矩阵乘法的Strassen算法详解

题目描述 请编程实现矩阵乘法,并考虑当矩阵规模较大时的优化方法. 思路分析 根据wikipedia上的介绍:两个矩阵的乘法仅当第一个矩阵B的列数和另一个矩阵A的行数相等时才能定义.如A是m×n矩阵和B是n×p矩阵,它们的乘积AB是一个m×p矩阵,它的一个元素其中 1 ≤ i ≤ m, 1 ≤ j ≤ p. 值得一提的是,矩阵乘法满足结合律和分配率,但并不满足交换律,如下图所示的这个例子,两个矩阵交换相乘后,结果变了: 下面咱们来具体解决这个矩阵相乘的问题. 解法一.暴力解法 其实,通过前面的分析

51nod 1137 矩阵乘法

基本的矩阵乘法 中间for(int j=0;i<n;i++)  //这里写错了   应该是j<n 晚上果然  效率不行 等会早点儿睡 //矩阵乘法 就是 两个矩阵 第一个矩阵的列 等与 第二个矩阵的行相同 // 然后ans[i][j] += a[i][k] * b[k][j]; #include<bits/stdc++.h> using namespace std; typedef long long ll; const int maxn = 150; int n; ll a[ma

矩阵乘法

矩阵加法就是相同位置的数字加一下,矩阵减法也类似 矩阵乘以一个常数,就是所有位置都乘以这个数 矩阵乘以矩阵 计算规则是,第一个矩阵第一行的每个数字(2和1),各自乘以第二个矩阵第一列对应位置的数字(1和1),然后将乘积相加( 2 x 1 + 1 x 1),得到结果矩阵左上角的那个值3 矩阵的本质就是线性方程式,两者是一一对应关系.如果从线性方程式的角度,理解矩阵乘法就毫无难度.下面是一组线性方程式 矩阵的最初目的,只是为线性方程组提供一个简写形式 下面是严格的证明.有三组未知数 x.y 和 t,

矩阵乘法&lt;简单总结&gt;

原理:矩阵相乘最重要的方法是一般矩阵乘积.它只有在第一个矩阵的 行数 和第二个矩阵的 列数 相同时才可进行.若A为m×n矩阵,B为n×p矩阵,则他们的乘积AB会是一个m×p矩阵. 若A=    a    b    c        d    e    f        g    h    i    B=    A    D        B    E        C    F    A*B=CC=    aA+bB+cC    aD+bE+cF        dA+eB+fC    dD+eE

POJ2778 DNA Sequence Trie+矩阵乘法

题意:给定N个有A C G T组成的字符串,求长度为L的仅由A C G T组成的字符串中有多少个是不含给定的N个字符串的题解: 首先我们把所有的模式串(给定的DNA序列)建Trie,假定我们有一个匹配串,并且在匹配过程到S[i]这个字符时匹配到了Trie上的某个节点t,那么有两种可能: 匹配失败:t->child[S[i]]为空,跳转到t->fail,因此t->fail一定不能是某个模式串的结尾: 匹配成功:跳转到t->child[S[i+1]],因此t->child[S[i

【CDQ】BZOJ 2738 矩阵乘法

题意:给你一个N*N的矩阵,不用算矩阵乘法,但是每次询问一个子矩形的第K小数 思路: 整体二分+二维树状数组 二分询问的答案mid,将数值小等mid的全部插入二维树状数组 然后查询每个矩阵内的元素个数,若数量>K-1则放左边,否则放右边 继续向下分治,左边二分l-mid,右边mid-r 代码: #include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include