社区讨论

调出必关(得用我的做法)

P1872回文串计数参与者 1已保存回复 0

讨论操作

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

当前回复
0 条
当前快照
1 份
快照标识符
@mjcuigaz
此快照首次捕获于
2025/12/19 20:28
3 个月前
此快照最后确认于
2025/12/21 13:05
3 个月前
查看原帖
0分,qwq,样例过了
CPP
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=3e7;
string s;
char a[N];
int l,len[N];
void mlc(string &s){
    int le=s.size();
    for(int i=0;i<le;i++){
        a[++l]='&';
        a[++l]=s[i];
    }
    a[++l]='&';
    a[0]='!';a[l+1]='@';
    int m=1,r=0;
    for(int i=1;i<=l;i++){
        if(i<=r){
            int j=2*m-i;
            len[i]=min(len[j],r-i+1);
        }
        while(a[i-len[i]]==a[i+len[i]])len[i]++;
        if(i+len[i]-1>r){
            r=i+len[i]-1;
            m=i;
        }
    }
}
signed main(){
    cin.tie(0);cout.tie(0);ios::sync_with_stdio(0);
    cin>>s;
    mlc(s);
    int ans=0;
    for(int i=2;i<l;i++){
        for(int j=i+2;j<l;j++){
            int sj=j/2*2,si=(i+1)/2*2;
            int k=(sj-si)/2;//计算中间有几个字母
            if(k<0)continue;
            int leni=min(len[i]/2,k),lenj=min(len[j]/2,k);
            ans+=(leni*lenj);
            int t=(i+leni-1-(j-lenj+1)+1)/2;//重叠字母部分
            if(t>0)ans-=(t*(t+1)/2);
        }
    }
    cout<<ans;
    return 0;
}

回复

0 条回复,欢迎继续交流。

正在加载回复...