LINK:如果我让你查回文你还爱我吗

了解到了这个模板题. 果然我不会写2333...

考试的时候想到了一个非常辣鸡的 线段树合并+莫队的做法 过不了不再赘述.

当然也想到了manacher不过不太会用 所以就自闭了。

这道题 容易考虑到manacher而不是PAM.

考虑 在扩充后的字符串上做这个问题 这样就不需要考虑偶数回文串的条件了.

离线之后右端点不断移动 容易发现一个问题 某个点为中心的回文串个数标记在左端点上不过此时可能左端点够而右端点不太行。

一个trick 将区间分成两半 这样就没有这个影响了.

然后查询直接查就行了 可以线段树维护区间加当然也可以树状数组维护.

值得一提的是 可以发现每次赋值 某一段整体赋值很好做 在奇数回文串的时候这样做容易发现是两倍。

偶数则不然 这里减掉区间中所有的单独的#就可以发现 答案刚好是二倍了.

const int MAXN=200010<<1;
int n,Q;
struct jl{int l,r;int id;}sl[MAXN],sr[MAXN];
inline int cmpl(jl a,jl b){return a.r<b.r;}
inline int cmpr(jl a,jl b){return a.l>b.l;}
struct wy
{
int l,r;
ll sum,tag;
}t[MAXN<<2];
char a[MAXN],b[MAXN];
int p[MAXN];ll ans[MAXN];
inline void Manacher()
{
b[0]='#';b[1]='$';
rep(1,n,i)b[i<<1]=a[i],b[i<<1|1]='$';
n=n<<1|1;b[n+1]='0';
int mx=0,mid=0;
rep(1,n,i)
{
if(mx>i)p[i]=min(p[(mid<<1)-i],mx-i);
else p[i]=1;
while(b[i-p[i]]==b[i+p[i]])++p[i];
if(p[i]+i>mx)mx=p[i]+i,mid=i;
}
}
inline void pushdown(int p)
{
int mid=(l(p)+r(p))>>1;
sum(zz)+=(ll)tag(p)*(mid-l(p)+1);
sum(yy)+=(ll)tag(p)*(r(p)-mid);
tag(zz)+=tag(p);tag(yy)+=tag(p);
tag(p)=0;return;
}
inline void change(int p,int l,int r,int x)
{
if(l<=l(p)&&r>=r(p))
{
sum(p)+=(ll)(r(p)-l(p)+1)*x;
tag(p)+=x;return;
}
int mid=(l(p)+r(p))>>1;
if(tag(p))pushdown(p);
if(l<=mid)change(zz,l,r,x);
if(r>mid)change(yy,l,r,x);
sum(p)=sum(zz)+sum(yy);
}
inline ll ask(int p,int l,int r)
{
if(l<=l(p)&&r>=r(p))return sum(p);
int mid=(l(p)+r(p))>>1;ll cnt=0;
if(tag(p))pushdown(p);
if(l<=mid)cnt+=ask(zz,l,r);
if(r>mid)cnt+=ask(yy,l,r);
return cnt;
}
inline void build(int p,int l,int r)
{
l(p)=l;r(p)=r;
sum(p)=tag(p)=0;
if(l==r)return;
int mid=(l+r)>>1;
build(zz,l,mid);
build(yy,mid+1,r);
}
inline void solve_l()
{
build(1,1,n);int flag=1;
sort(sl+1,sl+1+Q,cmpl);
rep(1,n,i)
{
change(1,i-p[i]+1,i,1);
while(sl[flag].r<=i&&flag<=Q)
{
ans[sl[flag].id]+=ask(1,sl[flag].l,sl[flag].r);
++flag;
}
}
}
inline void solve_r()
{
build(1,1,n);int flag=1;
sort(sr+1,sr+1+Q,cmpr);
fep(n,1,i)
{
change(1,i,i+p[i]-1,1);
while(sr[flag].l>=i&&flag<=Q)
{
ans[sr[flag].id]+=ask(1,sr[flag].l,sr[flag].r);
++flag;
}
}
}
int main()
{
//freopen("1.in","r",stdin);
gt(n);gt(Q);gc(a);
Manacher();
rep(1,Q,i)
{
int get(l),get(r);
ans[i]-=(r-l+2);
l=l<<1;--l;r=r<<1;++r;
int mid=(l+r)>>1;
sl[i]=(jl){l,mid,i};
sr[i]=(jl){mid+1,r,i};
}
solve_l();solve_r();
rep(1,Q,i)putl(ans[i]>>1);
return 0;
}

牛客练习赛64 如果我让你查回文你还爱我吗 线段树 树状数组 manacher 计数 区间本质不同回文串个数的更多相关文章

  1. 牛客练习赛64 D【容斥+背包】

    牛客练习赛64 D.宝石装箱 Description \(n\)颗宝石装进\(n\)个箱子使得每个箱子中都有一颗宝石.第\(i\)颗宝石不能装入第\(a_i\)个箱子.求合法的装箱方案对\(99824 ...

  2. 牛客练习赛64 红色的樱花 exgcd 贪心

    LINK:The red sakura 暴怒狂樱 血染京都. 这题质量不咋地 这题也没啥营养. 不过还是存在值得学习的地方的. 一个trick n行 m列 第一行与第n行相连 第1列和第m列相连的时候 ...

  3. 【并查集缩点+tarjan无向图求桥】Where are you @牛客练习赛32 D

    目录 [并查集缩点+tarjan无向图求桥]Where are you @牛客练习赛32 D PROBLEM SOLUTION CODE [并查集缩点+tarjan无向图求桥]Where are yo ...

  4. 牛客练习赛31 B 赞迪卡之声妮莎与奥札奇 逻辑,博弈 B

    牛客练习赛31 B 赞迪卡之声妮莎与奥札奇 https://ac.nowcoder.com/acm/contest/218/B 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 2621 ...

  5. 牛客练习赛31 D 神器大师泰兹瑞与威穆 STL,模拟 A

    牛客练习赛31 D 神器大师泰兹瑞与威穆 https://ac.nowcoder.com/acm/contest/218/D 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 26214 ...

  6. 最小生成树--牛客练习赛43-C

    牛客练习赛43-C 链接: https://ac.nowcoder.com/acm/contest/548/C 来源:牛客网 题目描述 ​ 立华奏是一个刚刚开始学习 OI 的萌新. 最近,实力强大的 ...

  7. 牛客练习赛28-B(线段树,区间更新)

    牛客练习赛28 - B 传送门 题目 qn姐姐最好了~ ​ qn姐姐给你了一个长度为n的序列还有m次操作让你玩, ​ 1 l r 询问区间[l,r]内的元素和 ​ 2 l r 询问区间[l,r]内的 ...

  8. 牛客练习赛26:D-xor序列(线性基)

    链接:牛客练习赛26:D-xor序列(线性基) 题意:小a有n个数,他提出了一个很有意思的问题:他想知道对于任意的x, y,能否将x与这n个数中的任意多个数异或任意多次后变为y 题解:线性基 #inc ...

  9. [堆+贪心]牛客练习赛40-B

    传送门:牛客练习赛40 题面: 小A手头有 n 份任务,他可以以任意顺序完成这些任务,只有完成当前的任务后,他才能做下一个任务 第 i 个任务需要花费  x_i 的时间,同时完成第 i 个任务的时间不 ...

随机推荐

  1. 洛谷P5774,可爱的动态规划。

    如此可爱的动态规划见过么? 相信各位都非常喜欢动态规划,那我就写一道可爱的动态规划的题解吧. 题目:https://www.luogu.com.cn/problem/P5774 题意: 题意“挺明白” ...

  2. 结合实际需求,在webapi内利用WebSocket建立单向的消息推送平台,让A页面和服务端建立WebSocket连接,让其他页面可以及时给A页面推送消息

    1.需求示意图 2.需求描述 原本是为了给做unity3d客户端开发的同事提供不定时的消息推送,比如商城购买道具后服务端将道具信息推送给客户端. 本篇文章简化理解,用“相关部门开展活动,向全市人民征集 ...

  3. 通过调试对WriteFile()API的钩取

    通过调试对WriteFile()API的钩取 0x00 目标与思路 目标:钩取指定的notepad.exe进程writeFile()API函数,对notepad.exe进程的写入的字符保存时保存为大写 ...

  4. 【js】栈方法和队列方法

    栈方法:后进先出,推入(push)和弹出(pop):push("**")返回数组长度,pop()返回弹出的项. var colors = new Array(); // 创建一个数 ...

  5. gitlab-ci部署实现持续集成(centos7)

    一.gitlab安装 1. 环境准备 // selinux和 firewall 关闭 $ setenforce 0 $ sed -i "/^SELINUX/s/enforcing/disab ...

  6. HotSpot的类模型(4)

    我们继续接着上一篇 HotSpot的类模型(3)分析,这次主要分析表示java数组的C++类. 4.ArrayKlass类 ArrayKlass继承自Klass,是所有数组类的抽象基类,类及重要属性的 ...

  7. Python-01矩阵、数组和列表等的总结

    python的基础知识总结 使用到了numpy库,所以第一步需要 import numpy as np 1.创建矩阵 1.1一般矩阵的创建 创建一个二维的矩阵,并使用ndim.shape.size分别 ...

  8. Scala 基础(十一):Scala 函数式编程(三)高级(一)偏函数、作为参数的函数、匿名函数、高阶函数

    1 偏函数 1)在对符合某个条件,而不是所有情况进行逻辑操作时,使用偏函数是一个不错的选择 2)将包在大括号内的一组case语句封装为函数,我们称之为偏函数,它只对会作用于指定类型的参数或指定范围值的 ...

  9. java 面向对象(十一):关键字:package/import

    1.1 使用说明: * 1.为了更好的实现项目中类的管理,提供包的概念 * 2.使用package声明类或接口所属的包,声明在源文件的首行 * 3.包,属于标识符,遵循标识符的命名规则.规范(xxxy ...

  10. 07 drf源码剖析之节流

    07 drf源码剖析之节流 目录 07 drf源码剖析之节流 1. 节流简述 2. 节流使用 3. 源码剖析 总结: 1. 节流简述 节流类似于权限,它确定是否应授权请求.节流指示临时状态,并用于控制 ...