D. Distinct Characters Queries(一维set+思维)

在这里插入图片描述在这里插入图片描述
题意给你一个字符串,对这个字符串有两种操作:
1.把逻辑位置(也就是对应字符串下标为pos-1)位于pos的字符改为c;
2.统计位于逻辑区间[L,R]的不同的字符个数;
其实已读完这个,我马上想到用前缀和,但是一想,好像不行吧,因为对于字符的修改你怎么办呢?
所以换了一种思路,我想着线段树可不可以,但是又想,线段树结点存什么呢?
所以行不通,之后看了大佬的代码,我彻底被折服了;QAQ;
整体思路:把每个字符对应的下标存下来,然后问到区间有多少个不同字符的时候,直接枚举+用二分查找就可以找到这个 区间有多少个不同字符了;
AC代码:

#include<bits/stdc++.h>
using namespace std;
set<int> Set[26];//放26个字符
int main(){
	string s;
	cin>>s;
	for(int i=0;i<s.length();i++){
		  Set[s[i]-'a'].insert(i);//把 每个字符所占的下标给存起来
	}
	int n;
	scanf("%d",&n);
	int l,r,x;
	char ch;
	int op;
	int ans;
	for(int i=0;i<n;i++){
		ans=0;
		  scanf("%d",&op);
		  if(op==1){//对于操作1  改变字符,需要删除逻辑位置x上的字符,然后把新的字符加入新字符对应的集合
		  	scanf("%d %c",&x,&ch);
		  	char t=s[x-1];
		  	Set[t-'a'].erase(x-1);
		  	s[x-1]=ch;
		  	Set[ch-'a'].insert(x-1);
		  }else{
		  	scanf("%d %d",&l,&r);//二分查找时间复杂度为:log(n)不用担心超时
		  	l--;r--;
		  	for(int i=0;i<26;i++){
		  		if(Set[i].size()==0)continue;
		  		   set<int >::iterator it=Set[i].lower_bound(l);
		  		   if(it!=Set[i].end()&&*it<=r){
		  		   	     ans++;
					 }
			  }
			  printf("%d\n",ans);
		  }
	}
	return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值