首页 > 代码库 > [Manacher+bit]Palindrome
[Manacher+bit]Palindrome
https://nanti.jisuanke.com/t/15428
题目大意:离散表示的字符串,求其最长回文串长度。
解题关键:若只用Manacher算法,在统计sum时会超时,所以加一个树状数组来维护前n项和,即可AC。
注意进行Manacher时,i是从1开始的,不要小也不要大。
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 struct node{ 5 ll num; 6 char ch; 7 }s[100010]; 8 ll p[110010],sum[110010],bit[110010]; 9 ll t,n,a,k,id,maxlen,tt;10 ll read(ll i){11 ll res=0;12 while(i){13 res+=bit[i];14 i-=i&-i;15 }16 return res;17 }18 void add1(ll i,ll x){19 while(i<110010){20 bit[i]+=x;21 i+=i&-i;22 }23 }24 int main(){25 scanf("%lld",&t);26 while(t--){27 memset(p,0,sizeof p);28 memset(bit,0,sizeof bit);29 memset(s,0,sizeof s);30 memset(sum,0,sizeof sum);31 scanf("%lld",&n);32 k=0;33 for(int i=0;i<n;i++){34 k++;35 //cin>>s[k].num>>s[k].ch;36 scanf("%lld %c",&s[k].num,&s[k].ch);37 tt=s[k].num;38 if(s[k].ch==s[k-1].ch){39 s[k-1].num+=s[k].num;40 k--;41 }42 add1(k,tt);43 }44 id=0,maxlen=0;45 s[0].ch=‘*‘,s[k+1].ch=‘#‘;46 for(int i=1;i<=k;i++){47 if(p[id]+id>i) p[i]=min(p[2*id-i],p[id]+id-i);48 else p[i]=1; 49 while(s[i-p[i]].ch==s[i+p[i]].ch&&s[i-p[i]].num==s[i+p[i]].num)++p[i];50 if(p[i]+i>p[id]+id) id=i;51 sum[i]=read(i+p[i]-1)-read(i-p[i]); 52 if(s[i-p[i]].ch==s[i+p[i]].ch) sum[i]+=2*min(s[i-p[i]].num,s[i+p[i]].num);53 maxlen=max(maxlen,sum[i]);54 }55 printf("%lld\n",maxlen); 56 }57 return 0;58 }
[Manacher+bit]Palindrome
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。