专栏文章

题解:AT_arc164_d [ARC164D] 1D Coulomb

AT_arc164_d题解参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@miqie8ki
此快照首次捕获于
2025/12/04 05:18
3 个月前
此快照最后确认于
2025/12/04 05:18
3 个月前
查看原文
Link
dp 小水题。
注:洛谷翻译在某些细节上有问题,请到原网站查看题意。(因为比较复杂就不放了)

符号定义

sgn(x)={1x>00x=01x<0\operatorname{sgn}(x)=\begin{cases}1&x>0\\0&x=0\\-1&x<0\end{cases}

解法

我们注意到,原子移动的方向恒不变。那么如果把原子移动的左右看成左右括号的话,所有原子的序列正好可以构成一个合法括号序列。而相撞的原子一定是序列中一对匹配的括号。
根据以上结论,我们要求和的式子无非就变成了 i=12nsgn(Fi)×i\sum\limits_{i=1}^{2n}-\operatorname{sgn}(F_i)\times i,即括号互相匹配。
于是我们设 fi,jf_{i,j} 表示前 i+ji+j 个原子中,有 ii 个正原子、jj 个负原子的贡献。
因为我们要对所有情况求和,我们还需要令 gi,jg_{i,j} 表示方案数。
接下来推导转移:
i+ji+j 位置可以为正原子时:
  • gi,jgi,j+gi1,jg_{i,j}\gets g_{i,j}+g_{i-1,j}
  • fi,jfi,j+fi1,jsgn(2i2j1)(i+j)gi1,jf_{i,j}\gets f_{i,j}+f_{i-1,j}-\operatorname{sgn}(2i-2j-1)(i+j)g_{i-1,j}
负原子时同理。
时间复杂度 O(n2)O(n^2)
CODE:
CPP
//luogu paste jo5j6ogx
cst int N=3e3;
cst ll p=998244353;
string s;
int n;
ll f[N+10][N+10],g[N+10][N+10];
int main(void){
	ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
	cin>>n>>s;s="="+s;
	g[0][0]=1;
	for(int i=0;i<=n;i++){
		for(int j=0;j<=n;j++){
			if(!(i|j)) continue;
			if(s[i+j]!='-'&&i){
				g[i][j]=madd(g[i][j],g[i-1][j],p);
				f[i][j]=madd(f[i][j],f[i-1][j],p);
				f[i][j]=madd(f[i][j],-sgn<int>((i<<1)-(j<<1)-1)*g[i-1][j]%p*(i+j)%p,p);
			}
			if(s[i+j]!='+'&&j){
				g[i][j]=madd(g[i][j],g[i][j-1],p);
				f[i][j]=madd(f[i][j],f[i][j-1],p);
				f[i][j]=madd(f[i][j],sgn<int>((i<<1)-(j<<1)+1)*g[i][j-1]%p*(i+j)%p,p);
			}
		}
	}
	write(f[n][n]);
	ret 0;
}

评论

0 条评论,欢迎与作者交流。

正在加载评论...