题目大意

“优秀的拆分”指将一个字符串拆分成AABB的形式

十次询问,每次给出一个字符串S(\(|S|\leq3*10^4\)),求它的所有子串的优秀的拆分的方案数之和

题解

此题过于优秀,题解先坑着

代码
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<ctime>
#include<iomanip>
#include<iostream>
#include<map>
#include<queue>
#include<set>
#include<stack>
#include<vector>
#define rep(i,x,y) for(register int i=(x);i<=(y);++i)
#define dwn(i,x,y) for(register int i=(x);i>=(y);--i)
#define view(u,k) for(int k=fir[u];k!=-1;k=nxt[k])
#define maxn 30010
#define LL long long
using namespace std;
int read()
{
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)&&ch!='-')ch=getchar();
if(ch=='-')f=-1,ch=getchar();
while(isdigit(ch))x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
return x*f;
}
void write(LL x)
{
if(x==0){putchar('0'),putchar('\n');return;}
int f=0;char ch[20];
if(x<0)putchar('-'),x=-x;
while(x)ch[++f]=x%10+'0',x/=10;
while(f)putchar(ch[f--]);
putchar('\n');
return;
}
int t,n,a[2][maxn];
LL ans;
char s[maxn];
void add(int l,int r,int f){if(l<=r)a[f][l]++,a[f][r+1]--;}
void geta(){rep(i,1,n)a[0][i]+=a[0][i-1],a[1][i]+=a[1][i-1];return;}
struct SAM
{
int ch[maxn<<1][26],rt,lst,cnt,dis[maxn<<1],fa[maxn<<1],pos[maxn],tim,dfn[maxn<<1],st[20][maxn<<2],lg[maxn<<2],len;
int fir[maxn<<1],nxt[maxn<<1],v[maxn<<1],cnte,dep[maxn<<1];
char s[maxn];
void ade(int u1,int v1){v[cnte]=v1,nxt[cnte]=fir[u1],fir[u1]=cnte++;}
int gx(char c){return c-'a';}
void ext(int id)
{
int p=lst,np=++cnt,val=gx(s[id]);dis[np]=id,pos[id]=np,lst=np;
for(;p&&!ch[p][val];p=fa[p])ch[p][val]=np;
if(!p)fa[np]=rt;
else
{
int q=ch[p][val];
if(dis[q]==dis[p]+1)fa[np]=q;
else
{
int nq=++cnt;dis[nq]=dis[p]+1;
fa[nq]=fa[q],fa[q]=fa[np]=nq;
memcpy(ch[nq],ch[q],sizeof(ch[q]));
for(;p&&ch[p][val]==q;p=fa[p])ch[p][val]=nq;
}
}
}
void dfs(int u)
{
dfn[u]=++tim,st[0][tim]=u;
view(u,k){dep[v[k]]=dep[u]+1,dfs(v[k]),st[0][++tim]=u;}
}
int lcs(int x,int y)
{
x=dfn[pos[x]],y=dfn[pos[y]];
if(x>y)swap(x,y);
int len=y-x+1;
return dis[dep[st[lg[len]][x]]<dep[st[lg[len]][y-(1<<lg[len])+1]]?st[lg[len]][x]:st[lg[len]][y-(1<<lg[len])+1]];
}
void build()
{
rt=lst=cnt=1;
rep(i,1,len)ext(i);
rep(i,1,cnt)fir[i]=-1;
rep(i,1,cnt)ade(fa[i],i);lg[0]=-1;
dfs(rt);
rep(i,1,tim)lg[i]=lg[i>>1]+1;
rep(k,1,lg[tim])for(int i=1;i+(1<<k)-1<=tim;i++)
st[k][i]=dep[st[k-1][i]]<dep[st[k-1][i+(1<<(k-1))]]?st[k-1][i]:st[k-1][i+(1<<(k-1))];
}
void reset()
{
rep(i,1,cnt){dep[i]=fa[i]=dis[i]=dfn[i]=0;rep(j,0,25)ch[i][j]=0;}
rep(i,1,tim)st[0][i]=0;tim=cnt=rt=cnte=lst=0;
}
}pre,suf;
int main()
{
t=read();
while(t--)
{
scanf("%s",s+1);
n=strlen(s+1);ans=0;
rep(i,1,n)pre.s[i]=s[i],suf.s[i]=s[n-i+1];pre.len=suf.len=n;
pre.build(),suf.build();
rep(len,1,(n>>1))
{
for(int i=1;i+len<=n;i+=len)
{
int lp=pre.lcs(i,i+len),ls=suf.lcs(n-i+1,n-(i+len)+1);
if(lp+ls>len)add(max(i-len+1,i-lp+1),min(i,i+ls-len),1),add(max(i+len,i-lp+(len<<1)),min(i+len+len-1,i+len+ls-1),0);
}
}
geta();
rep(i,1,n-1)ans+=(LL)a[0][i]*(LL)a[1][i+1];
rep(i,0,n+1)a[0][i]=a[1][i]=0;pre.reset(),suf.reset();
write(ans);
}
return 0;
}
/*
4
aabbbb
cccccc
aabaabaabaa
bbaabaababaaba
*/

最新文章

  1. 【Infobright】infobright数据导入导出测试
  2. 主窗体里面打开子窗体&amp;&amp;打印饼图《Delphi 6数据库开发典型实例》--图表的绘制
  3. python流程控制语句 ifelse - 4
  4. 7款值得你心动的HTML5动画和游戏
  5. mysql中的JOIN用法总结
  6. Java / Android 基于Http的多线程下载的实现
  7. tap是什么意思
  8. python + selenium &lt;四&gt;
  9. eclipse配置maven + 创建maven项目(三)
  10. .NET: 谈谈共享项目 (Shared Project) 的使用
  11. Python -- Records项目学习
  12. eclipse new server Cannot create a server using the selected type 网上有两种办法,其实原理一样
  13. java事件监听机制
  14. ubuntu下zip文件操作
  15. JAVA核心技术I---JAVA基础知识(static关键字)
  16. JAVA四则运算(读写文件)
  17. zyb的面试(广工14届比赛)
  18. 一些angular/js/ts的坑和吐槽
  19. static ,const
  20. [转].Net连接池超时注意事项

热门文章

  1. IIS Express 的怪毛病 vs2013本机调试
  2. bootstrap -- col-sm-6 和 col-xs-6
  3. 文件重定向,getline()获取一样,屏幕输出流,格式控制符dec,oct,hex,精度控制setprecision(int num),设置填充,cout.width和file(字符),进制输入
  4. java平台利用jsoup开发包,抓取优酷视频播放地址与图片地址等信息。
  5. NDK编译STL
  6. zedboard中OLED源码
  7. Katalon
  8. 嵌入式学习笔记(综合提高篇 第一章) -- 利用串口点亮/关闭LED灯
  9. PHP生成excel(1)
  10. codeforces#FF(div2) D DZY Loves Modification