链接:登录—专业IT笔试面试备考平台_牛客网
来源:牛客网
热爱足球(仅限游戏)的炸鸡块君最近购买了FIFA22,并且沉迷于FIFA22的Rivals排位上分。
在该排位系统中,每局游戏可能有胜利(用W表示)、失败(用L表示)、平局(用D表示)三种结果,胜利将使得排位分加一、失败使排位分减一、平局使排位分不变。特别地,该排位系统有着存档点机制,其可以简化的描述为:若你当前的排位分是333的整倍数(包括0倍),则若下一局游戏失败,你的排位分将不变(而不是减一)。
现在,给定一个游戏结果字符串和若干次询问,你需要回答这些询问。
每次询问格式为(l,r,s)(l,r,s)(l,r,s),询问若你初始有sss分,按从左到右的顺序经历了[l,r][l,r][l,r]这一子串的游戏结果后,最终分数是多少。
#include<bits/stdc++.h>
using namespace std;
int n,m;
char s[200005];
int lc(int x){
return x<<1;
}
int rc(int x){
return x<<1|1;
}
struct node{
int l;
int r;
int val[3];
}tr[1000005];
void pushup(int u){
for(int i = 0;i < 3;i++){
int lv = i+tr[lc(u)].val[i];
tr[u].val[i] = tr[lc(u)].val[i] + tr[rc(u)].val[(lv%3+3)%3];
}
}
void build(int u,int l,int r){
tr[u] = {l,r};
if(l == r){
if(s[l] == 'W'){
tr[u].val[0] = 1;
tr[u].val[1] = 1;
tr[u].val[2] = 1;
}else if(s[l] == 'D'){
tr[u].val[0] = 0;
tr[u].val[1] = 0;
tr[u].val[2] = 0;
}else{
tr[u].val[0] = 0;
tr[u].val[1] = -1;
tr[u].val[2] = -1;
}
}else{
int mid = l+r>>1;
build(lc(u),l,mid);
build(rc(u),mid+1,r);
pushup(u);
}
}
int query(int u,int l,int r,int s){
if(l <= tr[u].l && tr[u].r <= r){
return tr[u].val[(s%3+3)%3];
}else{
int mid = tr[u].l+tr[u].r>>1;
int res = 0;
if(l <= mid) res += query(lc(u),l,r,s);
if(r > mid) res += query(rc(u),l,r,s+res);
return res;
}
}
int main()
{
ios::sync_with_stdio(false);
cin>>n>>m;
cin>>s+1;
build(1,1,n);
while(m--){
int l,r,v;
cin>>l>>r>>v;
cout<<v+query(1,l,r,v)<<endl;
}
return 0;
}