题意:略

先用题解的办法,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. Python3 tkinter基础 Canvas create_line 画实线与虚线

             Python : 3.7.0          OS : Ubuntu 18.04.1 LTS         IDE : PyCharm 2018.2.4       Conda ...

  2. repo forall -c 用法【转】

    本文转载自:https://blog.csdn.net/u010164190/article/details/78332484 .repo forall命令 # repo forall -help # ...

  3. fw-cloud-framework项目配置、启动问题

    1.config组件:其配置优先级高于每个注册到同一个中心的工程的本地配置,所以在统一以dev这个 profile启动各个项目时,去config中心中找-dev结尾的各个工程名命名的文件. confi ...

  4. ORM框架 之 Entity Framework

    Entity Framework 1.ADO.NET Entity Framework是以ADO.NET为基础所发展出来的对象关系对应(O/R Mapping)解决方案,早起被称为ObjectSpac ...

  5. HDU 3333 Turing Tree(树状数组/主席树)

    题意 给定一个长度为 \(n​\) 的序列,\(m​\) 个查询,每次查询区间 \([L,R]​\) 范围内不同元素的和. \(1\leq T \leq 10\) \(1 \leq n\leq 300 ...

  6. Appium典型问题处理

    1. http://ask.testfan.cn/article/902 Appium 服务端安装-windows2. http://ask.testfan.cn/article/1078 最新版本a ...

  7. FZU oj 2277 Change 树状数组+dfs序

    Problem 2277 Change Time Limit: 2000 mSec    Memory Limit : 262144 KB  Problem Description There is ...

  8. 对前台传过来的实体是否为空 进行为空校验的N种方法

    首先定义一个注解,如下 import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import j ...

  9. base64 加密原理 解密原理

    假设需要加密的字符串是Jasmine 具体转换步骤: 第一步 将待转换的字符串转为一个个字符第二步 计算每一个字符对应的ASCII码十进制第三步 计算出十进制对应的二进制,若不足8位,在前面添加0进行 ...

  10. java中如何认定一个变量和方法

    对于变量,用变量名就可以认定.对于a ,你不能要求它既是int,又是double.这是错误的: 同理,对于方法,它的方法签名是:方法名+参数     通过签名,已经认定一个方法.你不能要求一个方法有多 ...