首页 > 其他分享 >Atcoder题解:Agc013_e

Atcoder题解:Agc013_e

时间:2023-04-16 16:44:59浏览次数:39  
标签:Atcoder matrix Agc013 int 题解 ty rd res dp

我们考虑转化题意,一个合法的将 \(1\sim N\) 划分成长度依次为 \(a_1,a_2,\cdots a_k\) 的小区间,对答案的贡献为 \(a_1^2a_2^2\cdots a_k^2\)。

化贡献为方案数,我们在每个长度为 \(a_i\) 的小区间内放置两个独立的标记,每个合法的划分方案对放置标记方案种数的贡献恰好是其对最终答案的贡献权值。并且每个划分方案的标记方案互不重合。

然后我们就可以 \(dp\),设 \(dp_{i,mask}\) 表示目前处理到第 \(i\) 个小格子,目前区间已经安放标记的状态为 \(mask\) 的方案数量。其中 \(mask\) 是一个长度为 \(2\) 的二进制串,表示第一个和第二个标记分别有没有被放下。

然后考虑从 \(dp_i\) 到 \(dp_{i+1}\) 的转移,其实就是讨论:

  • 在 \(i\) 和 \(i+1\) 之间是否放置划分点

  • 在 \(i+1\) 这个位置怎么放标记

首先是不放置划分点,那么每个 \(mask\) 就只能转移到 \(new\wedge mask=mask\) 的状态,也就是 \(\{0\rightarrow 0,1,2,3\}\{1\rightarrow 1,3\}\{2\rightarrow 2,3\}\{3\rightarrow 3\}\)。

然后是放置划分点,首先上一个要已经放完标记,所以只能从 \(3\) 转移过去,而下面变成 \(0\),\(i+1\) 随便放,也就是 \(\{3\rightarrow 0,1,2,3\}\)。

我们发现,这样就可以矩阵快速幂了,在 \(i\in X\) 的时候,转移就是矩阵

\[D_1=\begin{pmatrix} 1 & 1 & 1 & 1\\ 0 & 1 & 0 & 1\\ 0 & 0 & 1 & 1\\ 0 & 0 & 0 & 1 \end{pmatrix}\]

在 \(i\notin X\) 的时候,就加上放置划分点的转移变成

\[D_2=\begin{pmatrix} 1 & 1 & 1 & 1\\ 0 & 1 & 0 & 1\\ 0 & 0 & 1 & 1\\ 1 & 1 & 1 & 2 \end{pmatrix}\]

注意两种 \(3\) 到 \(3\) 的转移是分开的,所以权值是 \(2\)。

然后用 \(X\) 中的数分段,段内部 \(D_2\) 矩阵快速幂,段和段之间用 \(D_1\) 乘上即可。

复杂度 \(O(4^3m\log n)\)(事实上可以做到 \(3\times 3\) 的矩阵,但是转移不如 \(4\times 4\) 来得直观)(但是跑得实在是很慢啊)


const int P=1000000007;
struct matrix{
	vt<vt<int> >a;
	matrix(){};
	matrix(int n,int m){
		vt<vt<int> >vv(n,vt<int>(m,0));
		a=vv;
	}
	matrix operator *(const matrix b)const{
		matrix res;
		vt<vt<int> >vv(a.size(),vt<int>(b.a[0].size(),0));
		rd(i,(int)a.size())rd(j,(int)b.a[0].size())rd(k,(int)b.a.size()){
			vv[i][j]=(vv[i][j]+1ll*a[i][k]*b.a[k][j]%P)%P;
		}
		res.a=vv;
		return res;
	}
};
matrix fpow(matrix a,ll k){
	if(k==1)return a;
	matrix res=fpow(a,k>>1);
	if(k&1)return res*res*a;
	return res*res;
}
int n,m,x[100005];
signed main(){
	ios::sync_with_stdio(false);
	cin.tie(0);
	cin>>n>>m;
	rp(i,m)cin>>x[i];x[m+1]=n;x[0]=-1;
	matrix dp(1,4);
	dp.a[0][0]=1;
	matrix tf(4,4),ty(4,4);
	rd(i,4)rd(j,4)if((i&j)==i)tf.a[i][j]=1;
	ty=tf;
	rd(i,4)ty.a[3][i]=1;
	ty.a[3][3]=2;
	matrix bb=fpow(ty,2);
	rep(i,1,m+1){
		int len=x[i]-x[i-1]-1;
		if(len>0)dp=dp*fpow(ty,len);
		if(i!=m+1)dp=dp*tf;
	}cout<<dp.a[0][3]<<endl;
	return 0;
}
//Crayan_r

标签:Atcoder,matrix,Agc013,int,题解,ty,rd,res,dp
From: https://www.cnblogs.com/jucason-xu/p/17323503.html

相关文章

  • CF题解
    D.ABGraph2000构造https://codeforces.com/problemset/problem/1481/D题解:由于只有两种边,我们可以枚举较小结构的特性并循环来构造整体解。对于任意两个点,[u->v,v->u]只有4种情况,对于[1,1],[0,0]直接得解,可以循环这个环来构造回文,否则[1,0],[0,1],注意到当所需回文为odd长时,......
  • abc249_f Ignore Operations 题解
    IgnoreOperations题意Takahashi有一个整数\(x\),初始\(x=0\)。有\(n\)次操作。第\(i\)次操作用两个整数\(t_i,y_i\)描述:如果\(t_i=1\),将整数\(x\)替换为\(y_i\)。如果\(t_i=2\),将整数\(x\)替换为\(x+y_i\)。Takahashi可以跳过其中至多\(K\)......
  • TJOI 2015 概率论 题解
    TJOI2015概率论题解题意求\(n\)个点随机生成的有根二叉树(所有互不同构的二叉树出现情况等概率)的叶子节点数的期望值。题解70答案显然是\(\dfrac{g(n)}{f(n)}\),\(g(n)\)是\(n\)个点为所有二叉树的叶子总数,\(f(n)\)是\(n\)个点能生成的二叉树数。一棵树可以用左......
  • AtCoder 板刷 / vp 记录
    ARC104AtCoder传送门A题解一道小学数学题,$X=\frac{A+B}{2},Y=\frac{A-B}{2}$。B题解一道暴力题。发现子串合法的充要条件是$cnt_{\text{A}}=cnt_{\text{T}}\landcnt_{\text{G}}=cnt_{\text{C}}$,暴力统计即可。C题解简单区间dp。发现$[1,2n]$可以拆......
  • abc249_d Index Trio 题解
    IndexTrio题意给定长度为\(n\)的整数序列\(a=(a_1,a_2,\dots,a_n)\)。请你求出有多少个整数三元组\((i,j,k)\)满足:\(1\leqslanti,j,k\leqslantN\)\(\frac{a_i}{a_j}=a_k\)数据范围\(1\leqslantn,a_i\leqslant2\times10^5\)思路转变式子:\(......
  • Ubuntu系统硬盘安装到其他的电脑上,网络连接不上问题解决
    把Ubuntu系统硬盘安装到其他的电脑上,网络连接不了在一台i5电脑上安装好ubuntu18.04后,把该系统磁盘安装到另外一台i5电脑上。系统可以成功启动,但是不能正常上网。解决办法如下:1)用下面这个命令查看本台电脑上可用的网络接口$ifconfig-a#查看可用的网络接口$iplinks......
  • 题解:【ABC298G】Strawberry War
    题目链接场上被F干碎了,没看见这个典题。原题差不多是这个吧......
  • 栈和队列经典题题解
    目录......
  • AtCoder Regular Contest 104 F Visibility Sequence
    洛谷传送门AtCoder传送门考虑连边\((i,p_i)\)(若\(p_i=-1\)则不连边),可以发现形成了一篇内向树森林且这个森林存在一个dfs序为\(1,2,...,n\)。这棵森林有如下性质:\(\forallv\inson_u,h_u>h_v\)\(\forallv,w\inson_u\landv<w,h_v\leh_w\)考虑一个\(p......
  • NOC 2022 初中组选择和编程题题解
    NOC2022初中组选择题和编程题题解注意:本文有几个问题:部分题目我也不确定答案,而且我水平不行,有些题目我还真不会,大家就把我的答案当个参考吧。目前有一大半的题目因为作者比较懒,暂时没写,空在那儿,可以下载原题自己做做。1初中组选拔赛原题链接,提取码:efy6。1.1选择题......