洛谷P10716【MX-X1-T4】「KDOI-05」简单的字符串问题(扩展kmp+set+二分+扫描线树状数组)

news2024/9/23 5:17:54

题目

思路来源

小羊肖恩

题解

羊神这个做法tql,当时只是机械地写,过了之后再想想,才觉得确实是nb

先扩展kmp(Z函数)预处理出来数组,记z[i]为i往后可以和前缀匹配的最大长度

对于每个询问(p,cnt),先离线归位到每个p所在的vector内,

然后扫描线,每个i有一个[i,i+z[i]-1]的区间,在这个区间内以j结尾时,和前缀的lcp固定为[i,j]

对于每个i,先特判只出现一次的情况

对于大于一次的情况,先二分当前最大的可行长度x,

这个需要预处理mn[i][j]表示前i个字符出现j次时的结尾处的最小下标,没有的话就是n+1

对于位置p,出现次数cnt,二分找到满足mn[x][cnt]<=p的最大x,

长度x的前缀出现了cnt次,那么短于长度x的前缀一定出现了cnt次,

然后[i,i+z[i]-1]的扫描线保证了以p结尾的一定是一个当前合法的A串,

这就保证了A在开头和结尾均出现,且总的出现次数不少于cnt次了

一开始暴力双指针预处理mn超时了,后来改成在set上二分就ac了

因为长的串对应的位置一定包含短串,所以可以按zi从大到小释放位置,放进set,在set里二分

代码

#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,b) for(int i=(a);i<=(b);++i)
#define per(i,a,b) for(int i=(a);i>=(b);--i)
typedef long long ll;
typedef double db;
typedef pair<int,int> P;
#define fi first
#define se second
#define pb push_back
#define dbg(x) cerr<<(#x)<<":"<<x<<" ";
#define dbg2(x) cerr<<(#x)<<":"<<x<<endl;
#define SZ(a) (int)(a.size())
#define sci(a) scanf("%d",&(a))
#define scll(a) scanf("%lld",&(a))
#define pt(a) printf("%d",a);
#define pte(a) printf("%d\n",a)
#define ptlle(a) printf("%lld\n",a)
#define debug(...) fprintf(stderr, __VA_ARGS__)
const int N=2e5+10;
struct BitPre{ // 求前缀和(可改为max等)
	int n,tr[N];
	void init(int _n){
		n=_n;
		memset(tr,0,(n+1)*sizeof(*tr));
	}
	void add(int x,int v){
		++x;
		for(int i=x;i<=n;i+=i&-i)
		tr[i]+=v;
	}
	int sum(int x){
		++x;
		int ans=0; 
		for(int i=x;i;i-=i&-i)
		ans+=tr[i];
		return ans;
	}
}tr;
int n,m,net[N],ans[N];
char s[N];
P ask[N];
vector<int>q[N],add[N],del[N],mn[N];
void extkmppre(char s[],int len){
	int i=0,j,pos;
	net[0]=len;
	while(i+1<len&&s[i]==s[i+1])i++;
	net[1]=i,pos=1;
	rep(i,2,len-1){
		if(net[i-pos]+i<net[pos]+pos){
			net[i]=net[i-pos];
		}
		else{
			j=net[pos]+pos-i;
			if(j<0)j=0;
			while(i+j<len&&s[j]==s[i+j])j++;
			net[i]=j,pos=i;
		}
	}
}
void init(){
	set<int>S;
	vector<vector<int> >in(n+1,vector<int>());
	rep(i,0,n-1){
		in[net[i]].pb(i);
	}
	per(i,n,1){
		for(auto &x:in[i]){
			S.insert(x);
		}
		int up=n/i+1;
		mn[i].resize(up);
		mn[i][0]=0;
		mn[i][1]=i-1;
		//printf("i:%d up:%d\n",i,up);
		rep(j,2,up-1){
			if(mn[i][j-1]>n){
				mn[i][j]=n+1;
				continue;
			}
			auto it=S.upper_bound(mn[i][j-1]);
			if(it==S.end()){
				mn[i][j]=n+1;
			}
			else{
				mn[i][j]=(*it)+i-1;
			}
			//printf("i:%d j:%d mn:%d\n",i,j,mn[i][j]);
		}
	}
	rep(i,0,n-1){
		add[i].pb(i);
		del[i+net[i]-1].pb(i);
	}
}
bool ok(int len,int cnt,int p){
	if(!len)return 1;
	if(1ll*len*cnt>p+1)return 0;
	return mn[len][cnt]<=p;
	//printf("len:%d ok:%1d\n",len,o);
	//"cnt:%d p:%d mn:%d net:%d\n",len,cnt,p,mn[len][cnt],net[p-len+1]);
	//return o;
}
int main(){
	sci(n);
	scanf("%s",s);
	extkmppre(s,n);
	// rep(i,0,n-1){
		// printf("i:%d z[i]:%d\n",i,net[i]);
	// }
	init();
	tr.init(n+1);
	sci(m);
	rep(i,1,m){
		sci(ask[i].fi);
		sci(ask[i].se);
		ask[i].fi--;
		q[ask[i].fi].pb(i);
	}
	rep(i,0,n-1){
		for(auto &x:add[i]){
			tr.add(x,1);
		}
		for(auto &x:q[i]){
			int p=ask[x].fi,c=ask[x].se;
			if(c==1){
				ans[x]=1;
				continue;
			}
			int l=0,r=n;
			while(l<=r){
				int mid=(l+r)/2;
				if(ok(mid,c,i))l=mid+1;
				else r=mid-1;
			}
			//printf("id:%d p:%d c:%d len:%d\n",x,p,c,r);
			if(r==0)ans[x]=0;
			else ans[x]=tr.sum(i)-tr.sum(i-r);
			// rep(j,1,i){
				// printf("%d ",tr.sum(j)-tr.sum(j-1));
			// }
			// puts("");
		}
		for(auto &x:del[i]){
			tr.add(x,-1);
		}
	}
	rep(i,1,m){
		printf("%d\n",ans[i]);
	}
	return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1915689.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Dify工作流中的变量聚合节点

一.定义 变量聚合节点&#xff08;原变量赋值节点&#xff09;负责整合不同分支的输出结果&#xff0c;确保无论哪个分支被执行&#xff0c;其结果都能通过一个统一的变量来引用和访问。这在多分支的情况下非常有用&#xff0c;可将不同分支下相同作用的变量映射为一个输出变量…

esp32硬件电路设计

ESP-IDF 入门指南 | 乐鑫科技 (espressif.com) ESP32-DevKitC V4 入门指南 - ESP32 - — ESP-IDF 编程指南 v5.1 文档 (espressif.com)

matlab仿真 模拟调制(上)

&#xff08;内容源自详解MATLAB&#xff0f;SIMULINK 通信系统建模与仿真 刘学勇编著第五章内容&#xff0c;有兴趣的读者请阅读原书&#xff09; 1.幅度调制 clear all ts0.0025; %信号抽样时间间隔 t0:ts:10-ts;%时间矢量 fs1/ts;%抽样频率 dffs/length(t); %fft的频率分…

Linux进程间通信:匿名管道 命名管道

Linux进程间通信&#xff1a;匿名管道 &命名管道 一、进程间通信目的二、什么是管道三、匿名管道创建3.1 系统调用原型3.2 匿名管道创建 四、内核创建匿名管道过程五、匿名管道性质5.1 匿名管道的4种特殊情况5.2 匿名管道的5种特性5.3 测试源代码 六、命名管道6.1 创建命名…

高中数学:立体几何-基本立体图形分类

一、常见空间几何体 二、多面体 1、棱柱 2、棱锥 3、棱台 4、相关关系 三、旋转体 1、圆柱 2、圆锥 3、圆台 4、球

LLM 模型压缩之一 | APT

0. 资源链接 论文: APT: Adaptive Pruning and Tuning Pretrained Language Models for Efficient Training and Inference. 项目: https://github.com/ROIM1998/APT 1.背景动机 现有的大模型压缩加速存在以下问题&#xff1a; PEFT: 可以低成本为下游任务微调&#xff0c;…

游戏AI的创造思路-技术基础-蒙特卡洛树搜索(1)

本篇介绍蒙特卡洛树搜索算法&#xff0c;AlphaGo用于围棋计算的应用就是基于蒙特卡洛树搜索研发的~~~ 目录 1. 定义 2. 发展历史 3. 公式和函数 3.1.算法的公式和函数 3.2. Python实现公式和函数 4. 运行原理 4.1. 运行原理 4.2. 各步骤用Python代码 5. 优缺点和缺陷的…

免费听书TV版v1.0.1

使用非常稳定流畅&#xff0c;UI界面设计美观简洁&#xff0c;纯净无广。资源虽然不是特别多&#xff0c;但是日常听书还是可以满足需求。 完全免费&#xff0c;操作简单方便&#xff0c;安装即用&#xff0c;没有任何限制。 可以适配遥控器操作&#xff0c;OK键开启或关闭语…

适配各种IT场景的零信任沙箱

在当今数字化时代&#xff0c;网络安全威胁层出不穷&#xff0c;传统的安全防御策略已难以应对日益复杂的网络攻击。零信任与沙箱技术的结合&#xff0c;作为一种新兴的安全防护策略&#xff0c;正逐渐受到企业和组织的青睐。本文将深入探讨零信任结合沙箱技术所能解决的问题及…

【智能算法改进】一种混合多策略改进的麻雀搜索算法

目录 1.算法原理2.改进点3.结果展示4.参考文献5.代码获取 1.算法原理 【智能算法】麻雀搜索算法&#xff08;SSA&#xff09;原理及实现 2.改进点 精英反向学习策略 将精英反向学习策略应用到初始化阶段, 通过反向解的生成与精英个体的选择, 不仅使算法搜索范围得到扩大, 提…

C++第四弹 -- 类与对象(中上) (构造函数 析构函数 拷贝构造函数)

目录 前言构造函数1. 概念2. 特征 析构函数1. 概念2. 特征 拷贝构造函数1. 概念2. 特征 总结 前言 让我们一起揭开 C 对象生命周期管理的神秘面纱&#xff0c;掌握构造函数、析构函数和拷贝构造函数的精髓&#xff01; 博客主页: 酷酷学!!! 期待更多好文, 点击关注~ 构造函…

英伟达今年在华销售额预计将达120亿美元、MiniMax创始人:三年后才会出现“杀手级”AI应用

ChatGPT狂飙160天&#xff0c;世界已经不是之前的样子。 更多资源欢迎关注 1、英伟达今年在华销售额预计将达120亿美元 芯片咨询公司SemiAnalysis报告预估&#xff0c;今年英伟达有望在中国销售价值约120亿美元的人工智能芯片。黄仁勋曾表示&#xff0c;希望借助新的芯片使得…

SprintBoot创建遇到的问题

最近使用IDEA版本为2022.3.1&#xff0c;java版本为21.0.3&#xff0c;现在做一个创建SprintBoot3的一个大体流程 1.先下载Maven&#xff0c;解压到一个位置 maven下载 2.配置setting.xml文件 这路径自己配置&#xff0c;这里不多演示 代码如下&#xff1a; <mirror>&…

【测试开发】--安全渗透测试

1. 安全渗透 1.1 分类 web数据库安全web应用服务器安全&#xff08;文件上传漏洞、文件包含漏洞&#xff09;web客户端安全&#xff08;XSS跨站攻击&#xff09; 2. sql注入 2.1 sql注入介绍 sql注入在安全问题中排行榜首sql注入攻击是输入参数未经过滤&#xff0c;然后直…

高考完的假期想学c语言要注意那些问题?

c语言算是现代编程语言里面比较简单的一个&#xff0c;对于高考刚考完的学生来说确实很适合刚好我有一些资料&#xff0c;是我根据网友给的问题精心整理了一份「c语言的资料从专业入门到高级教程」&#xff0c; 点个关注在评论区回复“888”之后私信回复“888”&#xff0c;全…

防火墙之安全策略

目录 前言&#xff1a; 一、实验需求 二、需求分析 三、具体操作 1&#xff0c;在安全区域中新建拓扑图中所显示的区域 2&#xff0c;在对象模块中的时间段中添加一个9&#xff1a;00-18&#xff1a;00 3&#xff0c;写两条安全策略&#xff0c;一个是生产区&#xff0c…

构建与操作共享栈

归纳编程学习的感悟, 记录奋斗路上的点滴, 希望能帮到一样刻苦的你! 如有不足欢迎指正! 共同学习交流! 🌎欢迎各位→点赞 👍+ 收藏⭐ + 留言​📝既然选择了远方,当不负青春,砥砺前行! 共享栈是一种优化的栈实现方式,它允许两个或多个栈共享同一段连续的内存空间…

(TGRS,2024)KG-ZSL:利用基于知识图谱的零样本学习模型识别未知灾难场景

文章目录 Recognizing Unknown Disaster Scenes With Knowledge Graph-Based Zero-Shot Learning (KG-ZSL) Model相关资料摘要引言方法总体框架视觉-语义特征提取过程TransD交互式注意力模块 多特征整合用于零样本推理 实验 Recognizing Unknown Disaster Scenes With Knowledg…

我以为我对Spring MVC很了解,直到我遇到了...

点赞再看&#xff0c;Java进阶一大半 所有人都知道Spring MVC是Rod Johnson是开发的&#xff0c;却鲜有人知道Spring MVC的理论基础来自于1978 年提出MVC模式的一个老头子&#xff0c;他就是Trygve Mikkjel Heyerdahl Reenskaug&#xff0c;挪威计算机科学家&#xff0c;奥斯陆…

【笔记】从零开始做一个精灵龙女-画贴图阶段(上)

此文只是我的笔记&#xff0c;不包全看懂&#xff0c;有问题可评论 PS贴图加工 1.打开ps 拖入uv图&#xff0c;新建图层&#xff0c;设置背景色为灰色&#xff0c;改一下图层名字 2.按z缩小一下uv图层&#xff0c;拖入实体uv图片&#xff08;目的是更好上色&#xff0c;比如…