NC14300. Palindrome
描述
输入描述
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.
输出描述
For each test case, output a integer donating the number of one-and-half palindromic substrings.
示例1
输入:
1 ababcbabccbaabc
输出:
2
说明:
In the example input, there are two substrings which are one-and-half palindromic strings, abab and abcbabc.C++(g++ 7.5.0) 解法, 执行用时: 309ms, 内存消耗: 10560K, 提交时间: 2022-09-29 21:14:04
#include<cstdio> #include<cstring> #define ri register int #define ll long long #define maxn 500005 #define fo(i,x,y) for(ri i(x);i<=y;++i) #define fd(i,x,y) for(ri i(x);i>=y;--i) using namespace std; struct node{ int l,r,pos; }a[maxn]; int T,n,d[maxn],c[maxn]; ll ans; char s[maxn]; inline ll min(ll x,ll y){ return x<y?x:y; } inline int lowbit(ri x){ return x&(~x+1); } inline void update(ri x){ for(;x<=n;x+=lowbit(x))++c[x]; } inline int query(ri x){ ri res(0);for(;x;x-=lowbit(x))res+=c[x]; return res; } inline void swap(node &x,node &y){ node t=x;x=y;y=t; } inline void qsort(ri l,ri r){ ri i=l,j=r,mid=a[l+r>>1].l; while(i<=j){ while(a[i].l<mid)++i;while(a[j].l>mid)--j; if(i<=j){ swap(a[i],a[j]);++i;--j; } } if(l<j)qsort(l,j);if(i<r)qsort(i,r); } int main(){ scanf("%d",&T); while(T--){ scanf("%s",s+1);n=strlen(s+1); ri l(0),r(0); fo(i,1,n)d[i]=0; fo(i,1,n){ if(i<=r){ ri j=l+r-i;d[i]=min(r-i+1,d[j]); if(d[j]<r-i+1)continue; } while(i-d[i]>=1&&i+d[i]<=n&&s[i-d[i]]==s[i+d[i]])++d[i]; if(i+d[i]-1>r)l=i-d[i]+1,r=i+d[i]-1; } //fo(i,1,n)printf("%d %d\n",i,d[i]); fo(i,1,n)a[i].l=i-d[i]+1;fo(i,1,n)a[i].r=i+d[i]-1;fo(i,1,n)a[i].pos=i; fo(i,0,n)c[i]=0;qsort(1,n);ri now(1);ans=0; fo(i,1,n){ while(now<=n&&a[now].l<=i)update(a[now++].pos); ans+=query(i+d[i]-1)-i; } printf("%lld\n",ans); } return 0; }
C++14(g++5.4) 解法, 执行用时: 400ms, 内存消耗: 13616K, 提交时间: 2019-04-16 14:48:20
#include<bits/stdc++.h> using namespace std; #define mst(a,b) memset(a,b,sizeof(a)) #define ll long long const int MAXN=5e5+5; char Ma[MAXN]; int Mp[MAXN]; void Manacher(char s[],int len){ //因为只需要求奇数长度的回文串,所以除了起始字符外不用添加特殊字符 int l=len+1; Ma[0]='$'; Ma[l]=0; int mx=0,id=0; for(int i=0;i<l;i++){ Mp[i]=mx>i?min(Mp[2*id-i],mx-i):1; while(Ma[i+Mp[i]]==Ma[i-Mp[i]]) Mp[i]++; if(i+Mp[i]>mx){ mx=i+Mp[i]; id=i; } } } int t; int c[MAXN]; int lowbit(int x){ return x&(-x); } void add(int x,int z=1){ while(x<MAXN){ c[x]+=z; x+=lowbit(x); } } int query(int x){ int res=0; while(x>0){ res+=c[x]; x-=lowbit(x); } return res; } struct node{ int d,pos; bool operator<(const node &p)const{//按差值排序 return d<p.d; } }a[MAXN]; int main(){ scanf("%d",&t); while(t--){ scanf("%s",Ma+1); int len=strlen(Ma+1); Manacher(Ma,len); mst(c,0); for(int i=1;i<=len;i++){ Mp[i]--; } ll ans=0; int cnt=0; for(int i=len;i>=1;i--){ a[cnt].d=i-Mp[i]; a[cnt].pos=i; cnt++; } sort(a,a+cnt); for(int i=1,j=0;i<len;i++){ while(j<cnt&&a[j].d<=i){ add(a[j].pos); j++; } ans+=query(i+Mp[i])-query(i); } cout<<ans<<"\n"; } return 0; }
C++11(clang++ 3.9) 解法, 执行用时: 685ms, 内存消耗: 13496K, 提交时间: 2017-11-13 22:34:28
#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; typedef long long ll; #define maxn 500005 #define maxm 1000005 struct node { int x,l; }q[maxm]; char s[maxm]; int len[maxm],c[maxm]; void Manacher(char *s) { s[0]='#'; int num=strlen(s+1); int mx=0,id=0; for(int i=1;i<=num;i++) { if(mx>i) len[i]=min(mx-i,len[2*id-i]); else len[i]=1; while(s[i-len[i]]==s[i+len[i]]) len[i]++; if(len[i]+i>mx) mx=len[i]+i,id=i; } } bool comp(node a,node b) { return a.l>b.l; } void add(int x,int n) { while(x<=n) c[x]++,x+=x&(-x); } int findsum(int x) { int res=0; while(x) res+=c[x],x-=x&(-x); return res; } int main(void) { int T; scanf("%d",&T); while(T--) { scanf("%s",s+1); Manacher(s); int num=strlen(s+1); for(int i=0;i<=num;i++) c[i]=0; for(int i=1;i<=num;i++) { q[i].x=i; q[i].l=i+len[i]-1; } sort(q+1,q+num+1,comp); int p=1;ll ans=0; for(int i=num;i>0;i--) { while(p<=num && q[p].l>=i) add(q[p++].x,num); ans+=findsum(i-1)-findsum(i-len[i]); } printf("%lld\n",ans); } return 0; }