[ABC242E] (∀x∀)题解

以下事实是显而易见的,但在解决此问题时非常重要。

  • 长度的回文 N N N 由其第一个唯一确定 ⌈ N 2 ⌉ \lceil \frac{N}{2} \rceil 2N 字符。

现在我们将通过示例来解释解决方案。

首先,我们考虑 S = S= S=ABCDE. 显然,如果前三个字符在字典顺序上小于或等于,则 ABB 5 5 5-由他们确定的字符回文在字典上小于 S S S .相反,如果前三个字符在字典顺序上大于或等于,则 ABD 5 5 5-由他们确定的字符回文在字典上大于 S S S.

问题是,如果第一个 3 3 3 回文字符是,即如果是?对于此字符串,比较第一个 ABCABCBA 3 3 3 字符不足以确定回文是否在字典上小于 S S S,所以我们必须实际将此字符串与 S S S.这一次,此字符串在字典顺序上小于或等于 S S S,所以它满足条件。我们必须计算的是回文的数量,其第一个 3 3 3 字符为…等等。这些可以以与计算基数整数相同的方式进行计数 AAAAABABBABC 26 26 26(因为每个字符串都可以解释为基数的整数 26 26 26 通过查看 A = 0 =0 =0B = 1 =1 =1,…,和Z = 25 =25 =25.

接下来,让我们考虑一下案例 S = S= S=DCBA. 这一次,我们可以做几乎相同的讨论。唯一的“问题”是当前两个字符的回文时,即.这一次,此字符串在字典顺序上大于 DCDC CD S S S,因此它不满足条件。

无论如何,可以通过确定以下两个问题来解决问题:

  • 有多少回文在字典上比“问题”回文(即,回文,其第一个 ⌈ N 2 ⌉ \lceil \frac{N}{2} \rceil 2N 字符等于 S S S)?

  • “问题”回文是否满足条件?

请注意,根据实现的不同,通过以下方式解决它可能更容易:

  • 计算在字典上小于或等于“问题”回文的回文数量
  • 将计数递减 1 1 1 如果“问题”回文不满足条件

在示例代码中,使用了此方法。

示例代码 (C++):

#include<bits/stdc++.h>
#define mod 998244353
 
using namespace std;
 
int main(){
  int tc;
  cin >> tc;
  while(tc>0){
    tc--;
    int n;
    string s;
    cin >> n >> s;
    long long cres=0;
    string target=s;
    int p=0,q=n-1;
    while(p<q){
      target[q]=target[p];
      p++;q--;
    }
    int last=(n-1)/2;
    for(int i=0;i<=last;i++){
      cres*=26;cres%=mod;
      cres+=(s[i]-'A');cres%=mod;
    }
    cres++;cres%=mod;
    if(s<target){cres+=(mod-1);cres%=mod;}
    cout << cres << '\n';
  }
  return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值