【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$。如果取$T$为$1*n$的行向量,那么每一步矩阵乘法的复杂度都是$O(n^2)$的。

于是可以使用这种方法大致判断出$A*B$是否等于$C$。随机出$T$矩阵,然后判断$(T*A)*B$与$T*C$是否相等即可。大约每组数据随机10次即可出解。

#include <cstdio>
#include <algorithm>
#define N 1010
using namespace std;
typedef long long ll;
ll a[N][N] , b[N][N] , c[N][N] , t[N] , v[N];
bool judge(int n)
{
	int cnt , i , j;
	ll sb , sc;
	for(cnt = 1 ; cnt <= 10 ; cnt ++ )
	{
		for(i = 1 ; i <= n ; i ++ ) t[i] = rand() % 999 + 1;
		for(i = 1 ; i <= n ; i ++ )
			for(v[i] = 0 , j = 1 ; j <= n ; j ++ )
				v[i] += t[j] * a[j][i];
		for(i = 1 ; i <= n ; i ++ )
		{
			for(sb = sc = 0 , j = 1 ; j <= n ; j ++ )
				sb += v[j] * b[j][i] , sc += t[j] * c[j][i];
			if(sb != sc) return 0;
		}
	}
	return 1;
}
int main()
{
	srand(20011011);
	int n , i , j;
	while(~scanf("%d" , &n))
	{
		for(i = 1 ; i <= n ; i ++ )
			for(j = 1 ; j <= n ; j ++ )
				scanf("%lld" , &a[i][j]);
		for(i = 1 ; i <= n ; i ++ )
			for(j = 1 ; j <= n ; j ++ )
				scanf("%lld" , &b[i][j]);
		for(i = 1 ; i <= n ; i ++ )
			for(j = 1 ; j <= n ; j ++ )
				scanf("%lld" , &c[i][j]);
		if(judge(n)) puts("Yes");
		else puts("No");
	}
	return 0;
}
时间: 2024-11-02 10:10:52

【bzoj2396】神奇的矩阵 随机化的相关文章

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>

[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次). 继续看题.这时候我们惊讶的发现了下