【bzoj5082】弗拉格 矩阵乘法

题目描述

给你n个flag,你要把每个染色成红黑白黄四色之一,满足:

1.相邻旗不能同色

2.白不能和黄相邻,红不能和黑相邻

3.不能存在连续三个球依次是“黑白红”或“红白黑”

4.翻转后相等视为等价

设不等价方案数为f(n),给定l,r,求

Sigma f(i),其中L<=i<=R模1000000007

输入

输入两个数l,r

l, r ≤ 10^9

输出

输出答案

样例输入

3 4

样例输出

23



题解

矩阵乘法

容易设出dp状态 $f[i][j][k]$ 表示前 $i$ 个flag,最后一个的颜色为 $j$ ,倒数第二个的颜色为 $k$ 的方案数。

显然这个dp方程可以使用矩阵乘法来加速转移,并使用计数器维护前缀和。

至于翻转后相等视为等价的问题,易知:答案=(总方案数+翻转后与原来相等的方案数)/2。于是求出反转后与原来相等的方案数即可。

容易发现偶数长度的中间两个一定相同,因此不存在偶数长度的回文串。

对于奇数长度,发现题目条件的限制是对称的(AB<=>BA,ABC<=>CBA),因此某长度为 $2k-1$ 的奇数长度回文串的个数即为长度为 $k$ 的串的个数。再次求 $\lceil\frac n2\rceil$ 的答案即可。

最后前缀相减即为最终答案。

时间复杂度 $O(9^3\log n)$

#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
#define N 1010
using namespace std;
int n , m , a[N][N] , c[N][N] , v[N] , tot;
bool solve(int mid)
{
	int i , j , k;
	for(i = 1 ; i <= m ; i ++ )
		for(j = i + 1 ; j <= m ; j ++ )
			c[i][j] = 0;
	for(i = 1 ; i <= n ; i ++ )
	{
		tot = 0;
		for(j = 1 ; j <= m ; j ++ )
			if(a[i][j] >= mid)
				v[++tot] = j;
		for(j = 1 ; j <= tot ; j ++ )
		{
			for(k = j + 1 ; k <= tot ; k ++ )
			{
				if(c[v[j]][v[k]]) return 1;
				c[v[j]][v[k]] = 1;
			}
		}
	}
	return 0;
}
inline char nc()
{
	static char buf[100000] , *p1 , *p2;
	return p1 == p2 && (p2 = (p1 = buf) + fread(buf , 1 , 100000 , stdin) , p1 == p2) ? EOF : *p1 ++ ;
}
inline int read()
{
	int ret = 0; char ch = nc();
	while(!isdigit(ch)) ch = nc();
	while(isdigit(ch)) ret = ((ret + (ret << 2)) << 1) + (ch ^ ‘0‘) , ch = nc();
	return ret;
}
int main()
{
	int i , j , l = 1 << 30 , r = 0 , mid , ans;
	n = read() , m = read();
	for(i = 1 ; i <= n ; i ++ )
		for(j = 1 ; j <= m ; j ++ )
			a[i][j] = read() , l = min(l , a[i][j]) , r = max(r , a[i][j]);
	while(l <= r)
	{
		mid = (l + r) >> 1;
		if(solve(mid)) ans = mid , l = mid + 1;
		else r = mid - 1;
	}
	printf("%d\n" , ans);
	return 0;
}
时间: 2024-07-31 00:03:03

【bzoj5082】弗拉格 矩阵乘法的相关文章

矩阵乘法的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

codevs矩阵乘法系列

T1:矩阵乘法板子题,练手. #include <map> #include <set> #include <cmath> #include <ctime> #include <queue> #include <stack> #include <cstdio> #include <string> #include <vector> #include <cstdlib> #include

基于OpenMP的矩阵乘法实现及效率提升分析

一.  矩阵乘法串行实现 例子选择两个1024*1024的矩阵相乘,根据矩阵乘法运算得到运算结果.其中,两个矩阵中的数为double类型,初值由随机数函数产生.代码如下: #include <iostream> #include <omp.h> // OpenMP编程需要包含的头文件 #include <time.h> #include <stdlib.h> using namespace std; #define MatrixOrder 1024 #def

C语言 &#183; 矩阵乘法 &#183; 算法训练

问题描述 给定一个N阶矩阵A,输出A的M次幂(M是非负整数) 例如: A = 1 2 3 4 A的2次幂 7 10 15 22 输入格式 第一行是一个正整数N.M(1<=N<=30, 0<=M<=5),表示矩阵A的阶数和要求的幂数 接下来N行,每行N个绝对值不超过10的非负整数,描述矩阵A的值 输出格式 输出共N行,每行N个整数,表示A的M次幂所对应的矩阵.相邻的数之间用一个空格隔开 样例输入 2 21 23 4 样例输出 7 1015 22 代码如下: #include<s