首页 > 其他分享 >BZOJ1461字符串的匹配

BZOJ1461字符串的匹配

时间:2023-06-12 16:33:26浏览次数:39  
标签:匹配 BZOJ1461 int tree nex 字符串 bit include 5211314

题目
具体思路与KMP板子很像;
大致思路是将两个数字的排名来当字符比较
用树状数组 \(log_2(n)\) 的复杂度来找排名。
一定要注意边界问题
具体实现思路可以看代码
(PS:有奆佬说这题很板子,也许是我太弱了叭QAQ)

//9:30  开始写题,有些思路
//  40  思路被pass,不会写了
//  55  决定去看kmp板子及思想找思路 
//      其主要思想是当出现字符串不匹配的情况时,
//	    可以知道一部分之前已经匹配的的文本内容,
//      利用这些信息避免从头再去做匹配,而其中前缀表担负重任。 
//      也许有用??? 
//10:50 什么思路依然没有,感觉不会,要寄
//11:30 看题解吧,寄寄寄
//15:30 看了题解也学不会呜呜呜┭┮﹏┭┮
//16:20 蛙趣,终于整明白这道题了
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>

using namespace std;

int n, m, s;
int a[5211314 >> 3], b[5211314 >> 3], bit[5211314 >> 3];
int rank1[5211314 >> 3], rank2[5211314 >> 3], nex[5211314 >> 3];
int ans[5211314 >> 2], tot;

struct BinaryIndexedTree {
	inline int lowbit(int x) {
		return (x & (-x));
	}
	inline void Add(int x, int val) {
		while (x <= s) {
			bit[x] += val;
			x += lowbit(x); 
		}
		return;
	}
	inline int Query(int x) {
		int ans = 0;
		while (x > 0) {
			ans += bit[x];
			x -= lowbit(x);
		}
		return ans;
	}
}tree;

inline bool compared(int x, int y) {
	if (tree.Query(y) == rank1[x] && tree.Query(y - 1) == rank2[x]) {
		return true;
	}
	else {
		return false;
	}
}

int main() {
	cin >> n >> m >> s;
	for (int i = 1; i <= n; ++ i) cin >> a[i];
	for (int i = 1; i <= m; ++ i) {
		cin >> b[i];
		tree.Add(b[i], 1);
		rank1[i] = tree.Query(b[i]);
		rank2[i] = tree.Query(b[i] - 1);
		//将b数组的排名保存
	}
	memset(bit, 0, sizeof(bit));
	nex[0] = 1;
	for (int i = 2, j = 0; i <= m; ++ i) {
		tree.Add(b[i], 1);
		while (j > 0 && !compared(j + 1, b[i])) {
			for (int k = i - j; k < i - nex[j]; ++ k) {
				//注意,此时j没有加1。则i-j到i-nex[j] - 1为以j为下标的数组向右移动的长度
				//可以自己手模一下
				//因为下一个不能将nex[j]的点减去,所以
				tree.Add(b[k], -1);
			}
			j = nex[j];
		}
		if (compared(j + 1, b[i]) == true) j ++;
		//这里可以抽象的理解为每次b[j+1]与b[j]的排名名次的差和b[i]与b[i-1]的排名名次的差一样
		//也可以抽象的理解为每次加在的排名区间一样
		//(如在数组1,2,5后插入4中树状数组的bit[4]和bit[3] 
		// 与在数组1,2,10后插入5中的树状数组bit[5]与bit[4]的值一样)
		nex[i] = j;
	}//处理出来自己的nex
	memset(bit, 0, sizeof(bit));
	for (int i = 1, j = 0; i <= n; ++ i) {
		tree.Add(a[i], 1);
		while (j > 0 && !compared(j + 1, a[i])) {
			for (int k = i - j; k < i - nex[j]; ++ k) {
				tree.Add(a[k], -1);
			}
			j = nex[j];
		}
		if (compared(j + 1, a[i])) j ++;
		if (j == m) {
			ans[++ tot] = i - m + 1;
			for (int q = i - j + 1; q <= i - nex[j]; ++ q) {
				//此时j已经加1,所以这里i - j + 1到i - nex[j]为以j为下标的数组移动的长度
				//可以自己手模一下
				tree.Add(a[q], -1);
			}
			j = nex[j];
		}
	}
	cout << tot << endl;
	for (int i = 1; i <= tot; ++ i) {
		cout << ans[i] << endl;
	}
	return 0;
}

标签:匹配,BZOJ1461,int,tree,nex,字符串,bit,include,5211314
From: https://www.cnblogs.com/jueqingfeng/p/17475415.html

相关文章

  • java 去除字符串换行符
    *在正则表达式中\s表示所有的空格:匹配任何空白字符,包括空格、制表符、换页符等等。等价于[\f\n\r\t\v]。注意Unicode正则表达式会匹配全角空格符。*使用正则表达式,移除换行符(且不移除空格)**@paramoriginalStr原始字符串*@return移除换行\r、回车\n、制表\t符......
  • ORA-01861:文字与格式字符串不匹配?问题
       正常的按时间检索语句,报如上图所示错误:  原因:PURCHASE_DATE的数据类型不是date类型导致,解决方法为:给PURCHASE_DATE加一个to_date函数转换为时间类型的数据: ......
  • C# base64字符串转为图片保存到本地
    #regionBase64解码图片//<summary>///图片上传Base64解码///</summary>///<paramname="dataURL">Base64数据</param>///<returns>返回一个相对路径</returns>publicJsonResul......
  • Python 有S1和S2的字符串,S2是S1的子串,输出S1中不含S2的字符串
     思路:1. 先做替换,把S1与S2相同的子串替换为空2.有坑:第一步替换后,可能会出现新的字符串有包含S1中3.利用递归再去替换1a="tomcatisabigccatatandsmallcacatt-yyds"2b="cat"34defA(a,b):5ifbnotina:#先给个递......
  • Python判断字符串是否包含特定子串的7种方法(转)
    转自:Python判断字符串是否包含特定子串的7种方法在写代码的过程中,我们经常会遇到这样一个需求:判断字符串中是否包含某个关键词,也就是特定的子字符串。比如从一堆书籍名称中找出含有“python”的书名。判断两个字符串相等很简单,直接==就可以了。其实判断包含子串也非常容易,而且......
  • 去掉字符串两边的不可见字符(nbsp)方法
    /***参考String.trim,加入了不连续空格nbsp;( )unicode160和汉字空格unicode12288*@paramtext*@return*/publicstaticStringtrim(Stringtext){intlen=text.length();intst=0;char[]val=text.toCharArray();charp;while((st<len......
  • 对数据进行模糊匹配搜索(动态规划、最长公共子串、最长公共子序列)
    在搜索时常常在输入一半或者输入错误时,搜索引擎就给出智能提示。已知的搜索推荐主要包括以下几个方面:包含:“清华”和“清华大学”相似:“聊天软件”和“通讯软件”相关:“明星”和“刘亦菲”纠错:“好奇害死毛”和“好奇害死猫”其中包含模糊匹配可以使用动态规划算......
  • 对数据进行模糊匹配搜索(动态规划、最长公共子串、最长公共子序列)
    在搜索时常常在输入一半或者输入错误时,搜索引擎就给出智能提示。已知的搜索推荐主要包括以下几个方面:包含:“清华”和“清华大学”相似:“聊天软件”和“通讯软件”相关:“明星”和“刘亦菲”纠错:“好奇害死毛”和“好奇害死猫”其中包含模糊匹配可以使用动态规划算......
  • Luogu P3375 【模板】KMP字符串匹配
    【模板】KMP字符串匹配题目描述给出两个字符串\(s_1\)和\(s_2\),若\(s_1\)的区间\([l,r]\)子串与\(s_2\)完全相同,则称\(s_2\)在\(s_1\)中出现了,其出现位置为\(l\)。现在请你求出\(s_2\)在\(s_1\)中所有出现的位置。定义一个字符串\(s\)的border为\(s\)......
  • python整型/字符串/浮点 地址
    相同整数/浮点数/字符串-同一内存地址不同整数/浮点数/字符串-不同内存地址......