首页 > 其他分享 >F - Substring of Sorted String

F - Substring of Sorted String

时间:2023-01-16 11:00:30浏览次数:62  
标签:ch String int 字母 modify Substring && Sorted 逆序

题目链接

题解(树状数组)

我们维护两个树状数组,一个记录 \(1\sim i\) 中 \(s_i>s_{i+1}\)的数量,即逆序对数量,另一个记录 \(1\sim i\) 中 \(26\) 个字母的数量。

在修改时很好维护,先把原来的字母数量减 \(1\) ,再新的字母数加 \(1\) ,逆序对以类似方式维护。

重点在查询,一个区间 \([l,r]\) 被包含在排序后的字符串中,当且仅当这个区间里没有逆序对(即统计逆序对数量的树状数组 \([l,r-1]\) ,注意,右端点是 \(r-1\) ,如果右端点是 \(r\) 会统计到 \(s_r > s_{r+1}\) ,不符合我们要求),且除了最头上的字母外中间的字母(大于第一个字母小于最后一个字母)应和所有的字符数量相同(要包含排好序的字符串中连续字符一定要选上,如果 \([l,r]\) 区间的字符串包含了大于第一个字母小于最后一个字母的字母,那么中间的所有字母应包含整个字符串中的字母,也就是说,这个子串中中间的字母应和整个字符串中的字母书相同)。

代码

#include <iostream>
using namespace std;
const int N = 100010;
int n,q;
string s;
int c[N];
int cnt[26][N];
int lowbit (int x) {
	return x & -x;
}
void modify (int c[],int x,int d) {
	for (int i = x;i <= n;i += lowbit (i)) c[i] += d;
}
int query (int c[],int x) {
	int ans = 0;
	for (int i = x;i;i -= lowbit (i)) ans += c[i];
	return ans;
}
int main () {
	cin >> n >> s >> q;
	s = ' ' + s;
	for (int i = 1;i <= n;i++) modify (cnt[s[i] - 'a'],i,1);
	for (int i = 1;i < n;i++) {
		if (s[i] > s[i + 1]) modify (c,i,1);
	}
	while (q--) {
		int op;
		cin >> op;
		if (op == 1) {
			int x;
			char ch;
			cin >> x >> ch;
//			if (x + 1 <= n && s[x] > s[x + 1] && ch <= s[x + 1]) modify (c,x,-1);
//			else if (x + 1 <= n && s[x] <= s[x + 1] && ch > s[x + 1]) modify (c,x,1);
//			if (x - 1 >= 1 && s[x - 1] > s[x] && ch >= s[x - 1]) modify (c,x - 1,-1);
//			else if (x - 1 >= 1 && s[x - 1] <= s[x] && ch < s[x - 1]) modify (c,x - 1,1);
			modify (cnt[s[x] - 'a'],x,-1),modify (cnt[ch - 'a'],x,1);
			if (x - 1 >= 1 && s[x - 1] > s[x]) modify (c,x - 1,-1);
			if (x + 1 <= n && s[x] > s[x + 1]) modify (c,x,-1);
			s[x] = ch;
			if (x - 1 >= 1 && s[x - 1] > s[x]) modify (c,x - 1,1);
			if (x + 1 <= n && s[x] > s[x + 1]) modify (c,x,1);
		}
		else {
			int l,r;
			cin >> l >> r;
			bool ans = true;
			for (int i = s[l] - 'a' + 1;i <= s[r] - 'a' - 1;i++) ans &= query (cnt[i],r) - query (cnt[i],l - 1) == query (cnt[i],n);
			if (ans && query (c,r - 1) - query (c,l - 1) == 0) puts ("Yes");
			else puts ("No");
		}
	}
	return 0;
}

标签:ch,String,int,字母,modify,Substring,&&,Sorted,逆序
From: https://www.cnblogs.com/incra/p/17054906.html

相关文章

  • C++中string占用内存大小
    转自:https://blog.csdn.net/DLUTBruceZhang/article/details/98222351.例子intmain(){strings="abc";cout<<sizeof(s)<<"\n";cout<<sizeof(string)<<"......
  • 4. redis数据类型之String-bit
    Redis字符串string-bit前面我们介绍了Redis中的字符串类型的基本命令操作。但是没有涉及到bit相关的命令。本文我们来看几个bit相关的命令。bit相关的命令指的是bitcoun......
  • StringBuffer类
    StringBuffer类一、结构剖析Java.lang.StringBuffer代表可变的字符序列,可以对字符串内容进行增删。很多方法与String相同,但StringBuffer是可变长度的。String......
  • C++中如何将一行字符串(一行字符串可带空格)输入到string对象中或者字符数组中?
    提供两种方法:①、使用cin的成员函数getline,代码如下:charstr1[20];cin.getline(str1,20);     //第一个参数代表字符数组的指针,第二个参数代表写入的最大长度②、......
  • String常用方法
    intlength():返回字符串的长度:returnvalue.lengthcharcharAt(intindex):返回某索引处的字符returnvalue[index]booleanisEmpty():判断是否是空字符串:returnvalue.l......
  • 方便的格式化OutputDebugString输出函数
    OutputDebugString使用只能输入一个参数,在实际使用中带来很大的不便,下面改造后的函数就很好了,想怎么输出自己定。voidOutputDebugPrintf(constchar*strOutputString,........
  • 服务程序使用OutputDebugString,DbgView接收不到调试信息问题
    在服务程序中使用OutputDebugString输出调试信息后,发现DbgView接收不到调试信息,原来是我们少勾了一个选项。解决方法:菜单栏Capture-->CaptureGlobalWin32 勾上Ca......
  • C# 中的string是引用类型吗?
    注意如下区别!privatestringChangeString(stringsrc){src="123";returnsrc;}privatestringChangeRefString(refstringsrc){src="ref123"......
  • 涉及到字符串中有多个数据需要替换使用StringBuffer
    StringdocExtrefobjfield11=StringHelper.null2String(docMap.get("extrefobjfield11"));//团队成员StringBuilderupdatePeopleTeam=newStringBuilder();if(StringHe......
  • Power Strings
    PowerStrings题意求最大的循环节代码如果是循环的,也就是S=TTTTT那么ne[i]=TTTT,所以也就是前面的那一段长度。如果不相同,也就是abc,那么%的话,一定时为0的,妙代码#inc......