牛客练习赛64 如果我让你查回文你还爱我吗 线段树 树状数组 manacher 计数 区间本质不同回文串个数
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 计数 区间本质不同回文串个数的更多相关文章
- 牛客练习赛64 D【容斥+背包】
		牛客练习赛64 D.宝石装箱 Description \(n\)颗宝石装进\(n\)个箱子使得每个箱子中都有一颗宝石.第\(i\)颗宝石不能装入第\(a_i\)个箱子.求合法的装箱方案对\(99824 ... 
- 牛客练习赛64 红色的樱花 exgcd 贪心
		LINK:The red sakura 暴怒狂樱 血染京都. 这题质量不咋地 这题也没啥营养. 不过还是存在值得学习的地方的. 一个trick n行 m列 第一行与第n行相连 第1列和第m列相连的时候 ... 
- 【并查集缩点+tarjan无向图求桥】Where are you @牛客练习赛32 D
		目录 [并查集缩点+tarjan无向图求桥]Where are you @牛客练习赛32 D PROBLEM SOLUTION CODE [并查集缩点+tarjan无向图求桥]Where are yo ... 
- 牛客练习赛31 B 赞迪卡之声妮莎与奥札奇 逻辑,博弈 B
		牛客练习赛31 B 赞迪卡之声妮莎与奥札奇 https://ac.nowcoder.com/acm/contest/218/B 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 2621 ... 
- 牛客练习赛31 D 神器大师泰兹瑞与威穆 STL,模拟 A
		牛客练习赛31 D 神器大师泰兹瑞与威穆 https://ac.nowcoder.com/acm/contest/218/D 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 26214 ... 
- 最小生成树--牛客练习赛43-C
		牛客练习赛43-C 链接: https://ac.nowcoder.com/acm/contest/548/C 来源:牛客网 题目描述  立华奏是一个刚刚开始学习 OI 的萌新. 最近,实力强大的 ... 
- 牛客练习赛28-B(线段树,区间更新)
		牛客练习赛28 - B 传送门 题目 qn姐姐最好了~  qn姐姐给你了一个长度为n的序列还有m次操作让你玩,  1 l r 询问区间[l,r]内的元素和  2 l r 询问区间[l,r]内的 ... 
- 牛客练习赛26:D-xor序列(线性基)
		链接:牛客练习赛26:D-xor序列(线性基) 题意:小a有n个数,他提出了一个很有意思的问题:他想知道对于任意的x, y,能否将x与这n个数中的任意多个数异或任意多次后变为y 题解:线性基 #inc ... 
- [堆+贪心]牛客练习赛40-B
		传送门:牛客练习赛40 题面: 小A手头有 n 份任务,他可以以任意顺序完成这些任务,只有完成当前的任务后,他才能做下一个任务 第 i 个任务需要花费 x_i 的时间,同时完成第 i 个任务的时间不 ... 
随机推荐
- unity 自实现协程总结
			unity本人自实现了一个协程调用. 只是moveNext()的简单协程调用和封装,这个没什么好说的, 网上例子一大堆. 但使用的过程中遇到了几个问题. 1. 自己写的moveNext() 协程不能等 ... 
- DRS是啥你都不知道?不是吧,不是吧
			前言 最近写了很多数据库相关的文章,大家基本上对数据库也有了很多的了解,数据库本身有所了解了,我们是不是应该回归业务本身呢? 大家去了解过自己企业数据库的部署方式么?是怎么部署的,又是部署在哪里的?部 ... 
- Django setting设置 常用设置
			目录 Django配置文件基本设置 前言 setting配置汇总 一.APP路径 二.数据库配置 三.sql语句展示 四.静态文件目录 五.media文件配置 六.数据库中的UserInfo(用户表) ... 
- WeChat小程序开发-初学者笔记(一)
			WeChat小程序开发学习第一天: 完成学习目标: 1.安装并了解Wechat小程序的基本环境, 2.可以利用已学知识的结合简单实现helloWorld界面. 学习过程: 1.首先在微信平台上进行相关 ... 
- 微信支付之获取code
			微信支付之获取code, 1:访问下面的连接(自己拼) 2:去回调地址里拿code https://open.weixin.qq.com/connect/oauth2/authorize?appid= ... 
- java IO流 (八) RandomAccessFile的使用
			1.随机存取文件流:RandomAccessFile 2.使用说明: * 1.RandomAccessFile直接继承于java.lang.Object类,实现了DataInput和DataOutpu ... 
- java 基本语法(八) 数组(一) 数组的概述
			* 1.数组的理解:数组(Array),是多个相同类型数据一定顺序排列的集合,并使用一个名字命名, * 并通过编号的方式对这些数据进行统一管理. * * 2.数组相关的概念: * >数组名 * ... 
- Django框架09 /ajax、crsf、settings导入
			Django框架09 /ajax.crsf.settings导入 目录 Django框架09 /ajax.crsf.settings导入 1. ajax概述 2. ajax应用 3. ajax上传文件 ... 
- Python 为什么只需一条语句“a,b=b,a”,就能直接交换两个变量?
			从接触 Python 时起,我就觉得 Python 的元组解包(unpacking)挺有意思,非常简洁好用. 最显而易见的例子就是多重赋值,即在一条语句中同时给多个变量赋值: >>> ... 
- project facet java 1.8 is not supported解决办法
			Right click on project -> Properties -> Search for Project Facets -> Java (Version) 
