维护三棵线段树,当前%3余数是多少时的得分,进行push_up的时候,右区间对区间的贡献的影响需要加上左区间的影响。具体看代码,清晰易懂
#include <bits/stdc++.h>
#define endl '\n'
#define go continue
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define fory(i,a,b) for(int i = a; i <= b; ++i)
//-----
#define int long long
//-----
using namespace std;
template <typename T> inline void read(T& t)
{
int f = 0, c = getchar();
t = 0;
while (!isdigit(c)) f |= c == '-', c = getchar();
while (isdigit(c)) t = t * 10 + c - 48, c = getchar();
if (f) t = -t;
}
template <typename T> void print(T x)
{
if (x < 0) x = -x, putchar('-');
if (x > 9) print(x / 10);
putchar(x % 10 + 48);
}
inline void _sort(int* a, int l, int id)
{
id == 1 ? sort(a + 1, a + 1 + l, less<int>()) : sort(a + 1, a + 1 + l, greater<int>());
}
//--------------------------------------------
const int N = 2e5 + 10;
int n, m;
char s[N];
int x, y, z;
struct node
{
int l, r;
int c[3];
};
struct segment_tree
{
node t[N << 2];
inline void push_up(int root)
{
int ch = root << 1;
for(int i = 0; i < 3; ++i)
{
t[root].c[i] = t[ch].c[i] + t[ch + 1].c[(i + t[ch].c[i]) % 3];
}
}
inline void build(int root, int l, int r)
{
t[root].l = l;
t[root].r = r;
if(l != r)
{
int mid = (l + r) >> 1;
int ch = root << 1;
build(ch, l, mid);
build(ch + 1, mid + 1, r);
push_up(root);
}
else
{
if(s[l] == 'W')
{
t[root].c[0] = t[root].c[1] = t[root].c[2] = 1;
}
else if(s[l] == 'L')
{
t[root].c[0] = 0, t[root].c[1] = t[root].c[2] = -1;
}
else
{
t[root].c[0] = t[root].c[1] = t[root].c[2] = 0;
}
}
}
inline node query(int root, int l, int r)
{
if(t[root].l >= l && t[root].r <= r)
{
return t[root];
}
// cout<<"debug"<<endl;
int mid = (t[root].l + t[root].r) >> 1;
int ch = root << 1;
if(r <= mid) return query(ch, l, r);
else if(l > mid) return query(ch + 1, l, r);
else
{
node left = query(ch, l, mid);
node right = query(ch + 1, mid + 1, r);
node res;
for(int i = 0; i < 3; ++i)
{
res.c[i] = left.c[i] + right.c[(i + left.c[i]) % 3];
}
return res;
}
}
};
segment_tree st;
signed main()
{
read(n), read(m);
scanf("%s", s + 1);
st.build(1, 1, n);
while(m--)
{
read(x), read(y), read(z);
printf("%lld\n", st.query(1, x, y).c[z % 3] + z);
}
return 0;
}