bzoj2396 神奇的矩阵

传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2396

【题解】

我们随机一个1*n的矩阵D,根据矩阵乘法的结合律,如果A*B=C,右D*(A*B)=D*C,即(D*A)*B=C,那么矩阵乘法就是O(n^2)的复杂度了。

多随机几次即可。

# include <stdio.h>
# include <string.h>
# include <stdlib.h>
# include <algorithm>
// # include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;

inline int randi(int n) {
    return ((rand() << 15) + rand()) % n + 1;
}

int n;

struct mat {
    int n, m, a[510][510];
    inline void init (int _n, int _m) {
        n = _n, m = _m;
        memset(a, 0, sizeof a);
    }
}A, B, C, o, tA, tB, tC;

mat ta, tb, tc;
inline void mul() {
    tc.init(ta.n, tb.m);
    for (int i=1; i<=tc.n; ++i)
        for (int j=1; j<=tc.m; ++j)
            for (int k=1; k<=ta.m; ++k) tc.a[i][j] = tc.a[i][j] + ta.a[i][k] * tb.a[k][j];
}

int main() {
    while(~scanf("%d", &n)) {
        A.init(n, n); B.init(n, n); C.init(n, n);
        for (int i=1; i<=n; ++i)
            for (int j=1; j<=n; ++j) scanf("%d", &A.a[i][j]);
        for (int i=1; i<=n; ++i)
            for (int j=1; j<=n; ++j) scanf("%d", &B.a[i][j]);
        for (int i=1; i<=n; ++i)
            for (int j=1; j<=n; ++j) scanf("%d", &C.a[i][j]);

        for (int T = 1; T <= 10; ++T) {
            o.init(1, n);
            for (int i=1; i<=n; ++i)
                o.a[1][i] = randi(n);

            ta = o, tb = C;
            mul(); tC = tc;
            ta = o, tb = A;
            mul(); tA = tc;
            ta = tA, tb = B;
            mul(); tB = tc;

            for (int i=1; i<=n; ++i)
                if(tC.a[1][i] != tB.a[1][i]) {
                    puts("No");
                    goto END;
                }
        }
        puts("Yes");
        END:;
    }

    return 0;
}

时间: 2024-11-06 17:37:28

bzoj2396 神奇的矩阵的相关文章

【bzoj2396】神奇的矩阵 随机化

题目描述 给出三个行数和列数均为N的矩阵A.B.C,判断A*B=C是否成立. 输入 题目可能包含若干组数据.对于每组数据,第一行一个数N,接下来给出三个N*N的矩阵,依次为A.B.C三个矩阵. 输出 对于每组数据,若A*B=C成立,则输出Yes,否则No.每个答案占一行. 样例输入 1 2 2 100 样例输出 No 题解 随机化 如果直接把$A$与$B$的乘积算出来肯定会GG.. 考虑,如果$A*B=C$,那么$T*(A*B)=T*C$,而矩阵乘法具有结合律,因此有$(T*A)*B=T*C$.

[XJOI NOI2015模拟题13] A 神奇的矩阵 【分块】

题目链接:XJOI NOI2015-13 A 题目分析 首先,题目定义的这种矩阵有一个神奇的性质,第 4 行与第 2 行相同,于是第 5 行也就与第 3 行相同,后面的也是一样. 因此矩阵可以看做只有 3 行,从上到下就是 1 2 3 2 3 2 3 ...... 然后我们使用分块,将每一行分成 sqrt(m) 大小的块. 然后维护 A[i][j] —— 第一行前 i 块中,数字 j 的出现次数. 同时维护 B[i][j] —— 第二行前 i 块中,数字 j 的出现次数. 这里要将第一行的数字进

HDU 4291 A Short problem 又是一道神奇的矩阵

首先要知道一个姿势,对于Fib数列这类的东西,只要取余就一定会出现循环节.所以上来就直接暴力打表找规律就好了. MOD = 1000000007 发现循环节是 222222224. MOD = 2222222227 发现循环节是 183120 然后这个问题就解决了. 不要问我为啥会出现循环节,我也不会证明... ----------------------------------分割线---------------------------------- 我好像会证明了,试着证一发. 设有一个递推

swust oj 1126--神奇的矩阵(BFS,预处理,打表)

题目链接:http://acm.swust.edu.cn/problem/1126/ Time limit(ms): 1000 Memory limit(kb): 65535 上一周里,患有XX症的哈特13成功解决了填数矩阵问题.不知道他这一周又从哪儿弄来一神奇的矩阵,于是逃课潜心研究了一周,终于发现了其中的奥秘:该矩阵有2行.4列,即8个小方块,每个小方块上有一个数字,即:1 2 3 45 6 7 8对于这个神奇的矩阵,有3种变换方式,具体如下:变换A:上下两行数字互换,如上图可变为:5 6

大神刷题表

9月27日 后缀数组:[wikioi3160]最长公共子串 dp:NOIP2001统计单词个数 后缀自动机:[spoj1812]Longest Common Substring II [wikioi3160]最长公共子串 [spoj7258]Lexicographical Substring Search 扫描线+set:[poj2932]Coneology 扫描线+set+树上删边游戏:[FJOI2013]圆形游戏 结论:[bzoj3706][FJ2014集训]反色刷 最小环:[poj1734

【以前的空间】bzoj1009 [HNOI2008]GT考试

动态规划+kmp+矩阵快速幂 关于这题可以写出一个dp方程(f[i,j]表示准考证前i位中后j位为不吉利的数字的前j位的情况的个数) f[i,j]=Σf[i-1,k],其中j表示不吉利数字前k个数字加上某个数字后变成为不吉利数字的前j位(比如不吉利数字122123,然后现在k=5,那么如果填个3,j=6(123123):填个2,j=3(122):填个1,j=1(1):填个0,j=0. 然后我们就可以发现--好像可以用kmp算法来优化每次k+某个数字可以转移到的j的位置--因为j包括了前k个数字,

20150302模拟赛

T1 题目大意:我们有一个图和一些有向边,要求补无数条边使得其满足以下条件:1)i能到之后的所有点:2)边的终点比起点大:3)两点间最多一条边:4)如果j-i<=k,i到j的最短距离为j-i:5)如果j-i>k,i到j的最短距离为j-i或者j-i-k: 思路:考试的时候没有想出正解,不过想到了i只能向i+1或i+k+1连边,但是没有深入的展开.其实读完题目,应该得到的信息有:1)一定有i~i+1这条边,保证要求中的1):2)对于一个点,只能在向i+k+1连边:3)我们连的边一定在一个长度为k+

ACM数论之旅13---母函数(又叫生成函数)(痛并快乐着(╭ ̄3 ̄)╭)

(前排出售零食瓜子) 前言:(????不看会吃亏的) 接下来要讲的算法比较难,一般人听不懂,因为你不能用常人的思想去理解 就像高数(说多了都是泪( >﹏<.)) 你要用常规方法去想肯定很累( ̄▽ ̄)~* 有时候一直半解的多读几遍反而高效 就像矩阵,发明矩阵的人是天才,我们只能在使用矩阵的同时一直感叹:“哇!好神奇!这样也可以!” 而不是先研究为什么他会有这么多神奇的性质 因为,毕竟从发明者角度来说,他就是考虑了这么多才创造出了神奇的矩阵 而如果矩阵的每一个性质你都一点点研究过去,终有一天,你也

Luogu P3873 [TJOI2010]天气预报 题解

这题输入数据好坑啊.. 本题解是给像我一样的蒟蒻写的,可能略显啰嗦,已经懂了的大佬可以出门右转,去切掉IOI 我们先分析题目,将每一个\(w_i\),它的计算方式写成如下方式: \(w_i=a_1*w_{i-1}+a_2*w_{i-2}+\cdots+a_n*w_{i-n}\) 再注意到题中的这句话: a1, a2, ..., an是已知常数 所以这是一个常系数的线性递推方程.很自然的,对于这种方程,我们可以想到直接\(O(nm)\)递推(每个数都要乘n次). 继续看题.这时候我们惊讶的发现了下