题意:略

先用题解的办法,manacher,然后tag,add数组。但是比较难办的是manacher加了新的字符。这样的话cntL和cntR不是实际的值,但是没关系,原本的字符都在奇数位置,这样cntL[i]就等于(add[i]-tag[i])/2就是真实值,具体来说不好看,我看了3个小时才明白。比如

$#a#a#a#

12345678(下标)

01234321(radius)

那么第一个a,i=3时cntL+3,i=4时cntL+5,i=5时cntL+7。实际上是+1,+2,+3的。而tag表示它被加过几次。因此1+2+3=(3+5+7-3)/2;除法用逆元。

#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <iomanip>
#include <cstring>
#include <map>
#include <queue>
#include <set>
#include <cassert>
#include <stack>
#include <bitset>
#define mkp make_pair
using namespace std;
const double EPS=1e-;
typedef long long lon;
const lon SZ=,SSZ=*SZ,INF=0x7FFFFFFF,mod=;
char src[SSZ],ch[SSZ];
lon slen,clen,rd[SSZ];
lon cntr[SSZ],cntl[SSZ];
lon add[SSZ],tag[SSZ],inv; void init()
{
slen=strlen(src+);
clen=;
ch[++clen]='$';
ch[++clen]='#';
for(lon i=;i<=slen;++i)
{
ch[++clen]=src[i];
ch[++clen]='#';
}
} lon ext(lon ct,lon pos,lon &maxr,lon &maxid)
{
lon res=;
for(lon i=pos;i<=clen;++i)
{
lon ll=ct-(i-ct);
if(ch[ll]==ch[i])++res;
else break;
}
return res;
} void manacher()
{
lon maxr=,maxid=;
for(lon i=;i<=clen;++i)
{
if(i<=maxr)
{
lon rf1=maxid-(i-maxid);
lon rf2=maxid-(maxr-maxid);
lon ll=(rf1-rd[rf1]+);
if(ll>rf2)rd[i]=rd[rf1];
else rd[i]=(maxr-i+)+ext(i,maxr+,maxr,maxid);
}
else
{
rd[i]=ext(i,i,maxr,maxid);
}
if(i+rd[i]->maxr)
{
maxr=i+rd[i]-;
maxid=i;
}
}
} void work()
{
manacher();
for(lon i=;i<=clen;++i)
{
lon ll=i-rd[i]+,rr=i+rd[i]-;
++tag[ll],add[ll]+=(i+rd[i]-)+;
--tag[i+],add[i+]-=i;
}
for(lon i=;i<=clen;++i)
{
//cout<<tag[i]<<" "<<add[i]<<endl;
tag[i]+=tag[i-];
add[i]+=add[i-]-tag[i];
add[i]%=mod;
cntr[i]=(add[i]-tag[i])*inv%mod;
//cout<<cntr[i]<<endl;
}
for(lon i=;i<=clen+;++i)
{
tag[i]=add[i]=;
}
for(lon i=;i<=clen;++i)
{
lon rr=i+rd[i]-,ll=i-rd[i]+;
++tag[rr],add[rr]+=(i-rd[i]+)-;
--tag[i-],add[i-]-=i;
}
for(lon i=clen;i>=;--i)
{
tag[i]+=tag[i+];
add[i]+=add[i+]+tag[i];
add[i]%=mod;
cntl[i]=(add[i]-tag[i])*inv%mod;
}
for(lon i=;i<=clen+;++i)
{
tag[i]=add[i]=;
}
lon res=;
for(lon i=;i<clen;i+=)
{
//cout<<cntl[i]<<" "<<cntr[i+1]<<endl;
res+=cntl[i]*cntr[i+];
res%=mod;
}
res=(res+mod)%mod;
cout<<res<<endl;
for(lon i=;i<=clen+;++i)
{
cntl[i]=cntr[i]=rd[i]=;
}
} void ex_gcd(lon a,lon b,lon &x,lon &y,lon &d)
{
if(b==)
{
d=a,x=,y=;
}
else
{
ex_gcd(b,a%b,y,x,d);
y-=(a/b)*x;
}
} int main()
{
//std::ios::sync_with_stdio(0);
//freopen("d:\\1.txt","r",stdin);
lon x,y,d;
ex_gcd(,mod,x,y,d);
inv=x;
lon casenum;
//cin>>casenum;
//cout<<casenum<<endl;
//for(lon time=1;time<=casenum;++time)
for(int time=;scanf(" %s",src+)!=EOF;++time)
{
init();
work();
}
return ;
}

hdoj5785的更多相关文章

随机推荐

  1. 部署phpmyadmin登录不进去

    Centos7.5 部署phpmyadmin登录不进去 问题:明明输对了账号和密码就是登录不进去,但是用ip就能登录 解决方法:换个域名 [root@web01 code]# vim /etc/ngi ...

  2. hihoCoder week11 树中的最长路

    题目链接: https://hihocoder.com/contest/hiho11/problem/1 求树中节点对 距离最远的长度 #include <bits/stdc++.h> u ...

  3. jvm:垃圾收集器

    垃圾收集器: Serial 收集器: 单线程收集器,专注做收集,会暂停别的工作.收集效果好. ParNew 收集器: 是Serial的多线程版本.目前只有它能和CMS收集器配合.    Paralle ...

  4. (转)Introduction to Gradient Descent Algorithm (along with variants) in Machine Learning

    Introduction Optimization is always the ultimate goal whether you are dealing with a real life probl ...

  5. 2、iptables基本应用

    iptables:规则管理工具 添加.修改.删除.显示等: 规则和链有计数器: pkts:  由规则或链所匹配到的报文的个数: bytes:由规则或链匹配到的所有报文大小之和: iptables命令: ...

  6. 每天一个小程序—0013题(爬图片+正则表达式 or BeautifulSoup)

    第 0013 题: 用 Python 写一个爬图片的程序,爬 这个链接里的日本妹子图片 :-) 关于python3的urllib模块,可以看这篇博客:传送门 首先是用urlopen打开网站并且获取网页 ...

  7. Oracle DBHelper 第二版

    public static class OracleDBHelper { public static OracleCommand cmd = null; public static OracleCon ...

  8. JAVA中char和String/值类型和引用类型的区别

    import java.util.*; class test { public static void main(String[] args) { char a[] = {'b', 'a', 'c'} ...

  9. _battleground

    战场控制表 bgName 战场名字 bgTypeId 战场类型索引,请勿修改 cf 0 - 关闭混排:1 - 开启混排 limitHP 进入战场的最低血量,血量低于该值无法排此战场 maxRes 阿拉 ...

  10. Codeforces 769D k-Интересные пары чисел

    题目链接:http://codeforces.com/contest/769/problem/D 搜索题 考虑这些数的值域较小,直接${O(2^{k})}$次方枚举每个数字二进制位上是否改变,剪枝一下 ...