[atARC132E]Paw
结论:若有$k$个洞,至多只有$k+1$种不同的最终状态
考虑相邻两次操作,注意到除非两者(对应的洞在该时刻)相邻且方向正好相对,否则交换不影响最终状态
这种情况下,不妨将其中后操作的洞方向翻转(这也不影响),进而也即可交换
通过上述方式将操作按洞从左到右排序,那么一个洞向左会覆盖(左侧)所有段、向右仅会覆盖下一段
进一步的,取其中最后一次向左操作的洞,不难发现最终状态总是形如:其中一段与初始状态相同,左侧所有段方向均为向左,右侧所有段方向均为向右
显然这样只有$k+1$种状态,即得证
结合证明过程,考虑枚举与初始状态相同的一段,并统计该情况的概率
注意到两侧独立且等价,因此问题也即求$n$个洞时不覆盖到(从左到右)第$n$个洞右侧的概率$P_{n}$
考虑确定所有洞删除顺序后,限制即所有作为后缀最大值的洞必须向左
对于排列中的1,显然其不影响其余位置,且仅有$\frac{1}{2n}$的概率成为后缀最大值且向左,因此$P_{n}=\frac{2n-1}{2n}P_{n-1}$
时间复杂度为$o(n)$,可以通过
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define N 100005 4 #define mod 998244353 5 #define ll long long 6 int n,l,inv[N],P[N],a[N],cnt[N],ans; 7 char s[N]; 8 int main(){ 9 inv[0]=inv[1]=P[0]=1; 10 for(int i=2;i<N;i++)inv[i]=(ll)(mod-mod/i)*inv[mod%i]%mod; 11 for(int i=1;i<N;i++)P[i]=(ll)((i<<1)-1)*inv[i]%mod*(mod+1>>1)%mod*P[i-1]%mod; 12 scanf("%d%s",&l,s+1); 13 for(int i=1;i<=l;i++)cnt[i]=cnt[i-1]+(s[i]=='<'); 14 for(int i=1;i<=l;i++) 15 if (s[i]=='.')a[++n]=i; 16 a[n+1]=l+1; 17 for(int i=0;i<=n;i++){ 18 int s=(ll)P[i]*P[n-i]%mod; 19 ans=(ans+(ll)s*(a[i]+cnt[a[i+1]-1]-cnt[a[i]]))%mod; 20 } 21 printf("%d\n",ans); 22 return 0; 23 }