NC21587. 回文子序列计数
描述
输入描述
输入一行包含一个字符串,字符串的长度(1 <= N <= 3000)
输出描述
输出一个整数
示例1
输入:
axbcba
输出:
31
示例2
输入:
eeeee
输出:
14
示例3
输入:
zyzyzzzzxzyz
输出:
221
示例4
输入:
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
输出:
1044407608
C++(g++ 7.5.0) 解法, 执行用时: 38ms, 内存消耗: 572K, 提交时间: 2022-10-25 16:17:11
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=3e3+5; const int mod=1e9+7; ll X[N],dp[N]; char s[N]; int main(){ scanf("%s",s+1); int len=strlen(s+1); X[1]=1; X[len]=1; for(int i=2;i<len;i++){ X[i]=1; ll sum=0,cnt=0; for(int j=len;j>i;j--){ cnt=dp[j]; if(s[j]==s[i-1]){ dp[j]=(dp[j]+sum+1)%mod; } sum=(sum+cnt)%mod; X[i]=(X[i]+dp[j])%mod; } } ll ans=0; for(int i=1;i<=len;i++) ans=ans^(((i)*X[i])%mod); printf("%lld\n",ans); return 0; }
C++14(g++5.4) 解法, 执行用时: 45ms, 内存消耗: 612K, 提交时间: 2019-09-19 14:59:56
#include<bits/stdc++.h> using namespace std; const int mod=1e9+7; long long dp[3005],x[3005]; char s[3005]; int main(){ cin>>s; int n=strlen(s); x[0]=x[n-1]=1; for(int i=1;i<n-1;i++){ x[i]=1; int sum=0,cnt; for(int j=n-1;j>i;j--){ cnt=dp[j]; if(s[j]==s[i-1]) dp[j]=(dp[j]+sum+1)%mod; sum=(sum+cnt)%mod; x[i]=(x[i]+dp[j])%mod; } } long long ans=0; for(int i=0;i<n;i++) ans=ans^(((i+1)*x[i])%mod); cout<<ans<<endl; return 0; }
C++11(clang++ 3.9) 解法, 执行用时: 45ms, 内存消耗: 628K, 提交时间: 2019-09-13 13:24:27
#include<bits/stdc++.h> #define ll long long using namespace std; const int mod=1000000007; ll dp[3010],x[3010]; string s; int main() { cin>>s; int len=s.size(); x[0]=1,x[len-1]=1; for(int i=1;i<len-1;i++) { x[i]=1; ll sum=0,ans=0; for(int j=len-1;j>i;j--) { ans=dp[j]; if(s[j]==s[i-1]) dp[j]=(dp[j]+sum+1)%mod; sum=(sum+ans)%mod; x[i]=(x[i]+dp[j])%mod; } } ll ans1=0; for(int i=0;i<len;i++) ans1=ans1^(((i+1)*x[i])%mod); cout<<ans1<<endl; return 0; }