Codeforces - 1234D-- segment tree

Meaning of the questions: give you a string, then this string some operations, 1 xa is to replace the characters on the x position into a, 2 xy is to ask the interval [x, y] how many different characters have on;

With 1 << (s [i] - 'a') on behalf of this character, the line segment to maintain the tree, is noted |

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <string>
#include <iostream>
using namespace std;
const int N = 1e5+10;
char s[N];
int q,op,l,r;
char ch;
struct Node{
	int l,r,sum;
}tree[N<<2];
void build(int p,int l,int r){
	tree[p].l = l,tree[p].r = r;
	if(l==r){
		tree[p].sum = 1<<(s[l]-'a');
		return;
	}
	int mid = l+r>>1;
	build(p<<1,l,mid);
	build(p<<1|1,mid+1,r);
	tree[p].sum = tree[p<<1].sum|tree[p<<1|1].sum;
}
//单点更新 
void update(int p,int pos,int x){
	int l = tree[p].l,r = tree[p].r;
	if(l==r){
		tree[p].sum = 1<<x;
		return;
	}
	int mid = l+r>>1;
	if(pos <= mid){
		update(p<<1,pos,x);
	}else update(p<<1|1,pos,x);
	tree[p].sum = tree[p<<1].sum|tree[p<<1|1].sum;
}
int query(int p,int L,int R){
	int l = tree[p].l,r = tree[p].r;
	if(L<=l&&R>=r) return tree[p].sum;
	int mid = l+r>>1;
	int res = 0;
	if(L <= mid) res|=query(p<<1,L,R);
	if(R > mid) res|=query(p<<1|1,L,R);
	return res;
}
int main(){
	scanf("%s",s+1);
	int n = strlen(s+1);
	build(1,1,n);
	scanf("%d",&q);
	while(q--){
		scanf("%d",&op);
		if(op==1){
			scanf("%d %c",&l,&ch);
			update(1,l,ch-'a');	
		}else{
			scanf("%d %d",&l,&r);
			int res = query(1,l,r);
			int ans = 0;
			while(res){
				if(res&1) ans++;
				res>>=1;
			}
			printf("%d\n",ans);
		}
	}
	return 0;
}
Published 27 original articles · won praise 0 · Views 328

Guess you like

Origin blog.csdn.net/weixin_44083561/article/details/104652471