首页 > 其他分享 >[TJOI2019] 甲苯先生的字符串 题解

[TJOI2019] 甲苯先生的字符串 题解

时间:2024-10-14 22:01:26浏览次数:1  
标签:mathit int 题解 矩阵 cdots bmatrix TJOI2019 甲苯 vdots

T2 [TJOI2019] 甲苯先生的字符串

矩阵乘法优化 DP,所以一般来说这种 DP 都不怎么难。

30pts 的 DP 是裸的:设 \(f_{i,j}\) 为前 \(i\) 位、最后一位是 \(j\) 的方案数,则有转移方程:

\[f_{i,j}=\sum_{k=0}^{25}f_{i-1,k}\land k\ne j \]

想要矩阵优化,我们想到构造答案矩阵:

\[\mathit{ans}=\underbrace{\begin{bmatrix}1&1&1&\cdots&1\end{bmatrix}}_{\text{26个1}} \]

构造转移矩阵:

\[\mathit{base}=\begin{bmatrix}1&1&1&\cdots&1\\1&1&1&\cdots&1\\1&1&1&\cdots&1\\\vdots&\vdots&\vdots&\ddots&\vdots\\1&1&1&\cdots&1\end{bmatrix} \]

然后把不能相邻的位置点成 \(0\)。最终答案就是 \(\mathit{ans}\times\mathit{base}^{n-1}\) 之后 \(\sum\mathit{ans}_{0,i}\)。

#include<bits/stdc++.h>
#define int long long
using namespace std;

constexpr int MAXN=1e5+5,MOD=1e9+7;
int n;
string s1;
void add(int&x,int y){
	x=x+y>=MOD?x+y-MOD:x+y;
}
struct Matrix{
	int mx[26][26];
	Matrix(int x=0){
		memset(mx,0,sizeof(mx));
		if(x)for(int i=0;i<26;++i)mx[i][i]=x;
	}
	int*operator[](const int&x){
		return mx[x];
	}
	Matrix operator*(const Matrix&b)const{
		Matrix res;
		for(int i=0;i<26;++i)
			for(int k=0;k<26;++k)
				for(int j=0;j<26;++j)
					add(res[i][j],mx[i][k]*b.mx[k][j]%MOD);
		return res;
	}
}ans,base;
void print(Matrix x){
	for(int i=0;i<26;++i,cout<<'\n')
		for(int j=0;j<26;++j)
			cout<<x[i][j]<<' ';
}
Matrix power(Matrix a,int b){
	Matrix res=Matrix(1);
	for(;b;a=a*a,b>>=1)if(b&1)res=res*a;
	return res;
}

signed main(){
	ios::sync_with_stdio(0);
	cin.tie(nullptr),cout.tie(nullptr);
	cin>>n>>s1;
	for(int i=0;i<26;++i){
		ans[0][i]=1;
		for(int j=0;j<26;++j)base[i][j]=1;
	}
	for(int i=1;s1[i];++i)base[s1[i-1]-'a'][s1[i]-'a']=0;
	ans=ans*power(base,n-1);
	int res=0;
	for(int i=0;i<26;++i)add(res,ans[0][i]);
	cout<<res<<'\n';
	return 0;
}

标签:mathit,int,题解,矩阵,cdots,bmatrix,TJOI2019,甲苯,vdots
From: https://www.cnblogs.com/laoshan-plus/p/18466278

相关文章

  • [PA2021] Od deski do deski 题解
    T1[PA2021]Oddeskidodeski发现合法的字符串一定是类似\(\texttt{aa...aabb...bbcc...cc}\)的形式,也就是若干个\(\texttta\)、若干个\(\textttb\) 和若干个\(\textttc\) 等组成的形式。如果当前选好的串\(S_1\)是合法的,且有另一个合法的串\(S_2\),那么显然\(S_1......
  • 牛客周赛63部分题解
    比赛地址:牛客竞赛_ACM/NOI/CSP/CCPC/ICPC算法编程高难度练习赛_牛客竞赛OJ(nowcoder.com)A.小红的好数#include<bits/stdc++.h>usingnamespacestd;#definelllonglong#defineullunsignedlonglongvoidsolve(){lln;cin>>n;if(n>=10&&n<=99......
  • [ABC213G] Connectivity 2 题解
    好好好。我们设当前处理\(i\)的答案,那么最后的图就可以分成两个部分:\(1\)所在的联通块和其他,根据乘法原理,答案就是它们二者方案的乘积。设\(f_s\)表示集合\(s\)中所有点联通时图的情况数,\(g_s\)表示集合\(s\)中所有点不一定联通时图的情况数,则有:\[ans_i=\sum\limits......
  • [TJOI2019] 甲苯先生的字符串
    有点水了……考虑相邻的不能放在一起,不相邻的可以,那么很容易想到转移方程:\[dp_{i,j}=\sum_{k=0}^{25}dp_{i-1,k}[j,k不相邻]\]其中\(dp_{i,j}\)表示填了\(i\)位,最后一位填\(j\)。那结合数据范围,显然矩阵快速幂。时间复杂度\(O(26^3\logn)\),可以通过#include<bits/std......
  • 题解:P11132 【MX-X5-T4】「GFOI Round 1」epitaxy
    ProblemLink【MX-X5-T4】「GFOIRound1」epitaxy题目描述给你两个正整数\(n,m\)。定义一个\(1\simn\)的排列\(p\)的价值为所有的\(n-m+1\)个长度为\(m\)的连续子串内最大值的最大公因数。(规定单个数的最大公因数为其自身。)请你求出一个在所有\(1\simn\)......
  • 题解:P9137 [THUPC 2023 初赛] 速战速决
    ProblemLink[THUPC2023初赛]速战速决题目描述题意清晰,不再过多赘述。Solution每张不同的卡是等效的。小\(J\)手上的卡牌只有\(2\)种情况:手上没有相同的牌和有相同的牌。情况\(1\):小\(J\)手上的牌等价于\(1\simn\)(但其实没用),令其手上的牌为\(b_1,b_2,\ldo......
  • 题解:P6299 差别
    ProblemLink差别题目描述给定\(a,b,c,d\),求\(p,q,r,s\)使得\(M\)成为非零最小值。Solution\(M\)的表达式很复杂,把式子拆开有\(16\)个\(4\)次项,不难发现这是一个平方和,不断套平方和公式,最后化简成:\[M=|(ap+bq+cr-ds)^2+(-aq+bp+cs+dr)^2|=((a+bi)\times(......
  • 题解:P9743 「KDOI-06-J」旅行
    ProblemLink「KDOI-06-J」旅行题意题目讲的很清楚,不再过多赘述。Solution不难想到\(O(n^2\timesm^2\timesk)\)的做法:定义\(f_{i,j,val,x,y}\)为当前在\((x,y)\)的位置,花费\(val\)元,手上有\(x\)张\(L\)公司的票,\(y\)张\(Z\)公司的票的方案数,至于空间问题......
  • 题解:P1709 [USACO5.5] 隐藏口令 Hidden Password
    ProblemLink[USACO5.5]隐藏口令HiddenPassword题目描述求最小表示法的开头字母在原字符串的位置。Solution最小表示法板子,双指针解决即可。Code#include<iostream>#include<algorithm>#include<string.h>#include<cstring>#include<cmath>#include<cstdio>......
  • [PA2021] Od deski do deski 题解
    好题好题,难者不会会者不难,我是前者。实际上加入就可以合法的数是很好计算的。考虑现在所有前缀合法串后的字符实际上都可以满足条件。容易想到根据是否合法设置状态。设\(f_{i,j}/g_{i,j}\)表示现在填第\(i\)个数,有\(j\)个填了就合法的数,现在的串合法/不合法。那么有转......