链接:https://ac.nowcoder.com/acm/problem/21587
来源:牛客网
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 524288K,其他语言1048576K
64bit IO Format: %lld
题目描述
我们称正着读与反着读一样的串为回文串,比如abba与racecar都是回文串
我们称长度为奇数的回文为奇回文,中间的字符称为回文中心
有一个字符串S包含N个小写字母
令x[i]表示以i为回文中心的回文子序列的个数 (0 <= i <= N-1)
换句话说:保留第i个字符,X[i]表示有多少种字符的删除方案可以使得剩下的字符是一个以i为中心的回文串
Y[i] = ((i+1) * X[i])%1000000007
返回所有Y的xor之和
所有字母都是小写字母
输入描述:
输入一行包含一个字符串,字符串的长度(1 <= N <= 3000)
输出描述:
输出一个整数
示例1
输入
复制
axbcba
输出
复制
31
示例2
输入
复制
eeeee
输出
复制
14
示例3
输入
复制
zyzyzzzzxzyz
输出
复制
221
示例4
输入
复制
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
输出
复制
1044407608
备注:
子任务1:n<=100 子任务2:n<=500 子任务3:n<=3000
#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];//dp[i]代表以i为结尾的回文子序列数目(从右往左看))
char s[N];
int main(){
scanf("%s",s);
int len=strlen(s);
X[0]=1;
X[len-1]=1;
for(int i=1;i<len-1;i++){
X[i]=1;
ll sum=0,cnt=0;
for(int j=len-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;
}
}
ll ans=0;
for(int i=0;i<len;i++) ans=ans^(((i+1)*X[i])%mod);
printf("%lld\n",ans);
return 0;
}
版权声明:本文为qq_42936517原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。