D. Distinct Characters Queries

You are given a string s consisting of lowercase Latin letters and q

queries for this string.

Recall that the substring s[l;r]

of the string s is the string slsl+1…sr

. For example, the substrings of "codeforces" are "code", "force", "f", "for", but not "coder" and "top".

There are two types of queries:

  • 1 pos c

(1≤pos≤|s|, c is lowercase Latin letter): replace spos with c (set spos:=c

  • );
  • 2 l r

(1≤l≤r≤|s|): calculate the number of distinct characters in the substring s[l;r]

Input

The first line of the input contains one string s

consisting of no more than 105

lowercase Latin letters.

The second line of the input contains one integer q

(1≤q≤105

) — the number of queries.

The next q

lines contain queries, one per line. Each query is given in the format described in the problem statement. It is guaranteed that there is at least one query of the second type.

Output

For each query of the second type print the answer for it — the number of distinct characters in the required substring in this query.

思路:

        区间查询,区间修改,很明显就是线段树,主要是维护的是什么,首先线段树有个操作叫区间合拼,那么很容易我们就能想到集合操作里面的交集,那么我们可以用位运算,一个字母代表一位,然后取交集就行。

#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<string.h>
using namespace std;
int n,arr[400100];
char s[100100];
void bulid(int key,int l,int r)
{
	if(l>r)
		return;
	else if(l==r)
	{
		arr[key]=1<<(s[l]-'a');
	}
	else
	{
		int mid = (l+r)/2;
		bulid(key*2,l,mid);
		bulid(key*2+1,mid+1,r);
		arr[key]=arr[key*2]|arr[key*2+1];
	}
}
void udpate(int key,int l,int r,int wei,int value)
{
	if(r<l)
		return;
	if(l==r)
	{
		if(wei==l)
			arr[key]=1<<value;
	}
	else if(l<=wei&&r>=wei)
	{
		int mid = (l+r)/2;
		if(mid>=wei&&l<=wei)
			udpate(key*2,l,(l+r)/2,wei,value);
		if(mid+1<=wei&&r>=wei)
			udpate(key*2+1,(l+r)/2+1,r,wei,value);
		arr[key]=arr[key*2]|arr[key*2+1];
	}
}
int query(int key,int l,int r,int ql,int qr)
{
	if(r<ql||l>qr)
		return 0;
	if(l>=ql&&r<=qr)
	{
		return arr[key];
	}
	else
	{
		int ans=0;
		int mid = (l+r)/2;
		ans|=query(key*2,l,mid,ql,qr);
		ans|=query(key*2+1,mid+1,r,ql,qr);
		return ans;
	}
}
int main()
{
	scanf("%s",s+1);
	int len = strlen(s+1);
	cin>>n;
	bulid(1,1,len);
	for(int i=1;i<=n;i++)
	{
		int mark,wei,l,r;
		char temp;
		cin>>mark;
		if(mark==1)
		{
			cin>>wei>>temp;
			udpate(1,1,len,wei,temp-'a');
		}
		else
		{
			int ans=0;
			cin>>l>>r;
			int ret = query(1,1,len,l,r);
			while(ret)
			{
				if(ret&1)
					ans++;
				ret>>=1;
			}
			cout<<ans<<endl;
		}
	}
	return 0;
} 
发布了133 篇原创文章 · 获赞 8 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/fbher/article/details/102385674