hdoj5785
题意:略
先用题解的办法,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的更多相关文章
随机推荐
- P3041 [USACO12JAN]视频游戏的连击Video Game Combos
思路 简单的AC自动机上dp,暴力跳fail向子节点直接转移即可 代码 #include <cstdio> #include <algorithm> #include < ...
- UVA11270 Tiling Dominoes(轮廓线动态规划)
轮廓线动态规划是一种基于状态压缩解决和连通性相关的问题的动态规划方法 这道题是轮廓线动态规划的模板 讲解可以看lrj的蓝书 代码 #include <cstdio> #include &l ...
- 深度学习课程笔记(十六)Recursive Neural Network
深度学习课程笔记(十六)Recursive Neural Network 2018-08-07 22:47:14 This video tutorial is adopted from: Youtu ...
- Docker:Deploy your app
Prerequisites Install Docker. Get Docker Compose as described in Part 3 prerequisites. Get Docker Ma ...
- PTA 7-2 列车调度(25 分)
7-2 列车调度(25 分) 火车站的列车调度铁轨的结构如下图所示. 两端分别是一条入口(Entrance)轨道和一条出口(Exit)轨道,它们之间有N条平行的轨道.每趟列车从入口可以选择任意一条轨道 ...
- vue.js精讲02
2017-09-17 笔记及源码地址 : https://github.com/wll8/vue_note vue 中的事件深入. 事件: @click/mouseover…事件简写: @ 如 @cl ...
- ADO.NET DBHelper
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Da ...
- C# 获取程序运行目录
string a = "BaseDirectory:" + AppDomain.CurrentDomain.BaseDirectory + "\r\n" + & ...
- IIS上部署MVC网站,打开后ExtensionlessUrlHandler-4.0
IIS上部署MVC网站,打开后ExtensionlessUrlHandler-Integrated-4.0解决方法IIS上部署MVC网站,打开后500错误 IS上部署MVC网站,打开后Extensio ...
- ip啊
网络模型被OSI分成七层,TCP/IP协议大致对应了2.3.4.7层,分别是数据链路层.网络层.传输层.应用层,IP协议处于网络层上,它的工作原理说白了并不复杂: 整个互联网上所有的机器都有唯一一个I ...