题意

找如下子串的个数:

(l,r)是回文串,并且(l,(l+r)/2)也是回文串

思路

本来写了个回文树+dfs+hash,由于用了map所以T了

后来发现既然该子串和该子串的前半部分都是回文串,所以该子串的前半部分和后半部分是本质相同的!

于是这个log就去掉了

代码

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<string>
#include<stack>
#include<queue>
#include<deque>
#include<set>
#include<vector>
#include<map> #define fst first
#define sc second
#define pb push_back
#define mem(a,b) memset(a,b,sizeof(a))
#define lson l,mid,root<<1
#define rson mid+1,r,root<<1|1
#define lc root<<1
#define rc root<<1|1 using namespace std; typedef double db;
typedef long double ldb;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> PI;
typedef pair<ll,ll> PLL; const db eps = 1e-6;
const int mod = 1e9+7;
const int maxn = 8e5+100;
const int maxm = 2e6+100;
const int inf = 0x3f3f3f3f;
const db pi = acos(-1.0); const ull base = 201326611; ull po[maxn],ha[maxn]; ull getHash(int l, int r){
return ha[r]-ha[l-1]*po[r-l+1];
}
int ans[maxn];
int id[maxn];
struct pam{
int nx[maxn][26],num[maxn],cnt[maxn],fail[maxn];
int len[maxn],s[maxn],p,lst,n;
int newNode(int x){
mem(nx[p],0);
cnt[p]=num[p]=0;
len[p]=x;
return p++;
}
void init(){
p=0;newNode(0);newNode(-1);
lst=0;n=0;s[0]=-1;fail[0]=1;
}
int getFail(int x){
while(s[n-len[x]-1]!=s[n])x=fail[x];
return x;
}
void add(int x){
x-='a';
s[++n]=x;
int cur=getFail(lst);
if(!(lst=nx[cur][x])){//产生新节点
int now = newNode(len[cur]+2);
fail[now]=nx[getFail(fail[cur])][x];
nx[cur][x]=now;
num[now]=num[fail[now]]+1;
lst=now; id[now]=n;
}
cnt[lst]++;
}
void count(){
for(int i = p-1; i >= 0; i--)cnt[fail[i]]+=cnt[i];
for(int i = 2; i < p; i++){
int l = id[i]-len[i]+1;
int r = id[i];
int mid = (l+r)>>1;
if(len[i]%2==1&&getHash(l,mid)==getHash(mid,r))ans[len[i]]+=cnt[i];
if(len[i]%2==0&&getHash(l,mid)==getHash(mid+1,r))ans[len[i]]+=cnt[i];
}
}
}pam;
int n;
char s[maxn];
int main(){
po[0]=1;
for(int i = 1; i <= 3e5+10; i++){
po[i]=po[i-1]*base;
}
while(~scanf("%s",s+1)){
n=strlen(s+1);
pam.init();
for(int i = 1; i <= n; i++){
ans[i]=0;
ha[i]=ha[i-1]*base+s[i]-'a'+1;
pam.add(s[i]);
}pam.count();
for(int i = 1; i <= n; i++){
printf("%d", ans[i]);
if(i!=n)printf(" ");
}printf("\n");
}
return 0;
}
/* */

最新文章

  1. c#操作MangoDB 之MangoDB CSharp Driver驱动详解
  2. dsaf
  3. Git简易教程
  4. Spring Batch 批处理框架
  5. Linux下开发Windows平台运行的程序 - MinGW
  6. eclipse 下找不到或无法加载主类的解决办法[转]
  7. HDU 4767 Bell(矩阵+中国剩余定理)
  8. iOS开发面试题整理 (一)
  9. Qt qss一些伪装态,以及margin与padding区别
  10. /dev/shm(转)
  11. openresty 前端开发轻量级MVC框架封装二(渲染篇)
  12. 多线程编程-- part 3 多线程同步-&gt;synchronized关键字
  13. Java异常实战——OutOfMemoryError
  14. 我的第一个 react redux demo
  15. 在 Linux 平台中调试 C/C++ 内存泄漏方法(转)
  16. 基于jQuery果冻式按钮焦点图切换代码
  17. docker存储volume
  18. VMware常见错误故障排查
  19. Python3中内置类型bytes和str用法及byte和string之间各种编码转换
  20. 1z0-052 q209_4

热门文章

  1. 彻底掌握CORS跨源资源共享
  2. 【Java基础总结】多线程
  3. AspectJ——预编译方式实现AOP
  4. Navicat10.1.11使用记录
  5. Java Math类(java.lang包)
  6. 图解kubernetes调度器SchedulerCache核心源码实现
  7. NOIP2004普及组第3题 FBI树
  8. 云原生 - 体验Istio的完美入门之旅(一)
  9. 20190925Java课堂记录(二)
  10. [bzoj3991] [洛谷P3320] [SDOI2015] 寻宝游戏