求助线段树
查看原帖
求助线段树
200044
JS_TZ_ZHR楼主2020/6/12 21:33

RT

#include<bits/stdc++.h>
using namespace std;
int n,m,opt,x,y;
char s[500005],c;
struct Segment_tree {
	long long I,O,IO,OI,IOI;
} tree[500005<<2|1];
void push_up(int p) {
	int ls=p<<1,rs=p<<1|1;
	tree[p].I=tree[ls].I+tree[rs].I;
	tree[p].O=tree[ls].O+tree[rs].O;
	tree[p].IO=(tree[ls].I*tree[rs].O)+tree[ls].IO+tree[rs].IO;
	tree[p].OI=(tree[ls].O*tree[rs].I)+tree[ls].OI+tree[rs].OI;
	tree[p].IOI=(tree[ls].IO*tree[rs].I)+(tree[ls].I*tree[rs].OI)+tree[ls].IOI+tree[rs].IOI;
}
void build(int l,int r,int p) {
	if(l==r) {
		if(s[l]=='I')tree[p].I=1;
		else tree[p].O=1;
		return;
	}
	int mid=(l+r)>>1;
	build(l,mid,p<<1);
	build(mid+1,r,p<<1|1);
	push_up(p);
}
void change(int l,int r,int p,int now,char ch) {
	if(l==r) {
		tree[p].I=tree[p].O=0;
		if(ch=='I')tree[p].I=1;
		else tree[p].O=1;
		return;
	}
	int mid=(l+r)>>1;
	if(mid>=now)change(l,mid,p<<1,now,ch);
	else change(mid+1,r,p<<1|1,now,ch);
	push_up(p);
}
long long query(int l1,int r1,int l,int r,int p) {
	if(tree[p].IOI==0)return 0;
	if(l1<=l&&r<=r1)return tree[p].IOI;
	long long ans=0;
	int mid=(l+r)>>1;
	if(mid>=l1)ans+=query(l1,r1,l,mid,p<<1);
	if(r1>mid)ans+=query(l1,r1,mid+1,r,p<<1|1);
	return ans;
}
int main() {
	cin>>n>>m;
	for(int i=1; i<=n; i++)cin>>s[i];
	build(1,n,1);
	while(m--) {
		cin>>opt;
		if(opt==1) {
			cin>>x>>c;
			change(1,n,1,x,c);
		}
		if(opt==2) {
			cin>>x>>y;
			printf("%lld\n",query(x,y,1,n,1));
		}
	}
}
2020/6/12 21:33
加载中...