HDU 6230
Palindrome
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 433 Accepted Submission(s): 168
Problem Description
Alice like strings, especially long strings. For each string, she has a special evaluation system to judge how elegant the string is. She defines that a string abcbabc is one-and-half palindromic string, and abccbaabc is not. Now, Alice has generated some long strings. She ask for your help to find how many substrings which is one-and-half palindromic.abcbabc .For example, abab is one-and-half palindromic if and only if it satisfies
Input
The first line is the number of test cases. For each test case, there is only one line containing a string(the length of strings is less than or equal to 500000), this string only consists of lowercase letters.
Output
For each test case, output a integer donating the number of one-and-half palindromic substrings.
Sample Input
1
ababcbabccbaabc
Sample Output
2
Hint
In the example input, there are two substrings which are one-and-half palindromic strings, and .
Source
题意:
给出一个字符串,求有多少这样的子字符串S[1..3n−2](n≥2) 满足:S[i]=S[2n−i]=S[2n+i−2](1≤i≤n),例如 abcbabc 显然n是奇数。
代码:
//要求的就是回文半径相互覆盖的点对有多少,manacher预处理出来奇数长度回文串的中间点的回文半径,用优先队列记录一下到达j点最远能够覆 //盖到的位置,当到达i位置时更新队列(去掉没有用了的点,即到达不了i位置的点),树状数组求i位置前半径中有多少相互覆盖的点并把i加入队列。 #include<iostream> #include<cstdio> #include<cstring> #include<queue> #include<vector> using namespace std; typedef long long ll; const int MAXN=500009; char s[MAXN]; int t,n,p[MAXN<<2],a[MAXN<<2]; struct cmp{ bool operator () (int &a,int &b)const{ return a+p[a]>b+p[b]; } }; void manacher() { n=strlen(s+1); for(int i=1,mx=0,id=0;i<=n;i++){ p[i]=(mx>i?min(p[id*2-i],mx-i):1); while(s[i+p[i]]==s[i-p[i]]) p[i]++; if(i+p[i]>mx) { mx=i+p[i];id=i; } } for(int i=1;i<=n;i++) p[i]--; } void add(int id,int c) { while(id<=MAXN-9){ a[id]+=c; id+=((-id)&id); } } int query(int id) { int s=0; while(id){ s+=a[id]; id-=((-id)&id); } return s; } int main() { scanf("%d",&t); while(t--){ scanf("%s",s+1); manacher(); memset(a,0,sizeof(a)); ll ans=0; priority_queue<int,vector<int>,cmp>q; for(int i=2;i<=n;i++){ while(!q.empty()){ int now=q.top(); if(now+p[now]<i){ q.pop(); add(now,-1); }else break; } ans+=query(i-1)-query(i-p[i]-1); q.push(i);add(i,1); } printf("%lld\n",ans); } return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 【杂谈】分布式事务——高大上的无用知识?