[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 } 
View Code

 

posted @ 2021-12-29 10:43  PYWBKTDA  阅读(125)  评论(0编辑  收藏  举报