直接 fhp treap 平衡树维护区间 red,r,e,d,der,de,er,re,ed 的个数,考虑乘法原理即可

#include<bits/stdc++.h>
#define int long long
#define pc(x) putchar(x)
using namespace std;
int begintime=clock();
bool __ST__;
void write(int x){ if(x<0) x=-x,pc('-');if(!x) return ;write(x/10);pc(x%10+'0');return ;}
void wr(int x){ if(!x) pc('0');else write(x);return ;}
int read(){
	int res=0;char c=getchar();bool f=0;
	while(c<'0' || c>'9') c=='-'?f=1:f=f,c=getchar();
	while(c>='0' && c<='9') res=(res<<3)+(res<<1)+c-'0',c=getchar();
	return f?-res:res;
}
const int N=1e5+10;

mt19937 rnd(time(NULL));
int T=1,n,m,root,cnt;
int a[N];
struct node{
	int L,R,v;
	int r,e,d,re,ed,red;
	int er,de,der;
	int flip;
	unsigned long long pri;
	int si;
}tree[N];

void Flip(int o){
	tree[o].flip^=1;
	swap(tree[o].re,tree[o].er);
	swap(tree[o].ed,tree[o].de);
	swap(tree[o].red,tree[o].der);
	swap(tree[o].L,tree[o].R);
	return ;
}
void push_down(int o){
	if(!tree[o].flip) return ;
	Flip(tree[o].L),Flip(tree[o].R);
	tree[o].flip=0;
	return ;
}
void push_up(int o){
	node ls=tree[tree[o].L],rs=tree[tree[o].R];
	node i=tree[o];
	i.r=ls.r+rs.r,i.e=ls.e+rs.e,i.d=ls.d+rs.d;
	if(i.v==1) i.r++;
	if(i.v==2) i.e++;
	if(i.v==3) i.d++;
	i.re=ls.re+rs.re+ls.r*rs.e;
	if(i.v==1) i.re+=rs.e;
	if(i.v==2) i.re+=ls.r;
	i.ed=ls.ed+rs.ed+ls.e*rs.d;
	if(i.v==2) i.ed+=rs.d;
	if(i.v==3) i.ed+=ls.e;
	i.er=ls.er+rs.er+ls.e*rs.r;
	if(i.v==2) i.er+=rs.r;
	if(i.v==1) i.er+=ls.e;
	i.de=ls.de+rs.de+ls.d*rs.e;
	if(i.v==3) i.de+=rs.e;
	if(i.v==2) i.de+=ls.d;
	i.red=ls.red+rs.red+ls.re*rs.d+ls.r*rs.ed;
	if(i.v==1) i.red+=rs.ed;
	if(i.v==2) i.red+=ls.r*rs.d;
	if(i.v==3) i.red+=ls.re;
	i.der=ls.der+rs.der+ls.de*rs.r+ls.d*rs.er;
	if(i.v==1) i.der+=ls.de;
	if(i.v==2) i.der+=ls.d*rs.r;
	if(i.v==3) i.der+=rs.er;
	i.si=ls.si+rs.si+1;
	tree[o]=i;
	return ;
}
int newnode(int x){ 
	tree[++cnt]=((node){0,0,0,0,0,0,0,0,0,0,0,0,0,rnd(),1});
	if(x==1) tree[cnt].r++;
	if(x==2) tree[cnt].e++;
	if(x==3) tree[cnt].d++;
	tree[cnt].v=x;
	return cnt;
}
int merge(int L,int R){
	if(!L || !R) return L+R;
	if(tree[L].pri>tree[R].pri){
		push_down(L),tree[L].R=merge(tree[L].R,R);
		push_up(L);return L;
	}
	else{
		push_down(R),tree[R].L=merge(L,tree[R].L);
		push_up(R);return R;
	}
}
void split(int u,int x,int &L,int &R){
	if(!u) return L=R=0,void();
	push_down(u);
	if(tree[tree[u].L].si+1<=x) L=u,split(tree[u].R,x-tree[tree[u].L].si-1,tree[u].R,R);
	else R=u,split(tree[u].L,x,L,tree[u].L);
	push_up(u);
	return ;
}
void out(int x){
	if(!x) return;
	out(tree[x].L);
	printf("%d ",tree[x].r);
	out(tree[x].R);
}
void solve(){

	n=read(),m=read();
	for(int i=1;i<=n;i++){
		char c;cin>>c;
		if(c=='r') a[i]=1;
		if(c=='e') a[i]=2;
		if(c=='d') a[i]=3;
		root=merge(root,newnode(a[i]));
//		printf("%d ",tree[root].r);
	}
//	out(root);
//	printf("%d\n",tree[root].red);
	while(m--){
		int l=read(),r=read();
		int a,b,c;
		split(root,r,a,c);
		split(a,l-1,a,b);
		Flip(b);
		merge(merge(a,b),c);
		printf("%lld\n",tree[root].red);
		split(root,r,a,c);
		split(a,l-1,a,b);
		Flip(b);
		merge(merge(a,b),c);
//		out(1,1,n);
	}

	return ;
}
void clr(){

	return ;
}

bool __ED__;
signed main(){
// 	double MEM=((&__ED__)-(&__ST__))/1024.0/1024.0;
// 	fprintf(stderr,"%.2lf MB %.2lf GB\n\n",MEM,MEM/1024.0);
// 	freopen("in.in","r",stdin);
// 	freopen("out.out","w",stdout);

//  T=read();
	while(T--) solve(),clr();

// 	fprintf(stderr,"\n%d ms",clock()-begintime);
	return 0;
}

/*
6 2
rreedd
*/