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的更多相关文章
随机推荐
- Python3基础 list count 查询指定元素在列表中出现了多少次
Python : 3.7.0 OS : Ubuntu 18.04.1 LTS IDE : PyCharm 2018.2.4 Conda ...
- 彻底了解 suid, sgid ,sticky权限
sticky: 粘性的, 如 : sticky tape: 粘胶带 /tmp, /var/tmp: 位 sticky: 表示: 第一, 任何用户都可以在该目录下创建文件(编辑自己的文件),第二, 但是 ...
- 160CrackMe练手 002
首先查壳无壳,输入伪码报错,根据报错od查找字符串,定位到错误代码附近,可以看到有个条件跳转,改掉就可以爆破,接下来分析下注册算法,我们周围看看,从最近几个call看,并没有我们输入的用户名在堆栈中出 ...
- Install and Compile MatConvNet: CNNs for MATLAB --- Deep Learning framework
Install and Compile MatConvNet: CNNs for MATLAB --- Deep Learning framework 2017-04-18 10:19:35 If ...
- 【ASP.NET】System.Web.Routing - PageRouteHandler Class
用于提供一些属性和方法来定义如何将URL匹配到一个物理文件上面. public PageRouteHandler (string virtualPath, bool checkPhysicalUrlA ...
- Nuget 打包 for .Net Standart project
Create .NET Standard packages with Visual Studio 2015 Publishing packages nuge.exe 放在项目目录中 nuget spe ...
- Long类型转json时前端js丢失精度解决方案
一.问题背景 Java后端开发过程中,尤其是id字段,因数值太大,通过json形式传输到前端后,在js解析时,会丢失精度. 如果对精度丢失没有什么概念,可以看一个知乎的帖子,来感受一下:https:/ ...
- Python数据类型补充2
四.列表 常用操作+内置的方法: 1.按索引存取值(正向存取+反向存取):即可存也可以取 # li=['a','b','c','d'] # print(li[-1]) # li[-1]='D' # p ...
- 2、Python函数详解(0601)
函数的基础概念 1.函数是python为了代码最大程度的重用和最小化代码冗余而提供的基本程序结构: 2.函数是一种设计工具,它能让程序员将复杂的系统分解为可管理的部件: 3.函数用于将相关功能打包并参 ...
- 在centos6中编译安装httpd-2.4/搭建LAMP
首先确保centos6安装平台安装一下环境: #yum groupinstall "Development Tools" "Server Platform Develo ...