K题简单题解:

维护一段区域中, 最左端区间与最右端区间的方块高度。由于题目是单点修改, 所以可以去掉 操作, 仅保留最关键的 , 用 记录最左与最右端的红色方块数。

中, 由于蓝色方块会出现在上一排的右边, 所以我们设蓝色方块区间的最左端方块高度为 而最右端高度为 (这时我们假设一个蓝色方块要占两排, 左边那一排没有任何方块, 等与左边区间合并时再填入这个空格排) , 最后与蓝色方块合并的时候要注意 是否是 , 若 为零, 那么合并后的区间 。注意当 区间与 区间合并的时候, 若 区间的最左端方块堆内有红色方块, 那么 区间最右端的所有方块都要翻 倍且 区间内没有蓝色方块时, 我们可以发现 区间内的红色方块还可以在下一次区间合并时, 继续使 区间最右端的方块数翻 倍, 当然, 若 区间内没有蓝色方块且有红色方块那么合并区间 区间的红色方块数为 , 若 区间内有蓝色方块, 那么合并区间 区间的

#include <bits/stdc++.h>

using namespace std;

#define endl '\n'
#define int long long
#define IOS ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define rep(i, a, n) for (int i = a; i <= n; i++)
#define per(i, a, n) for (int i = n; i >= a; i--)
#define all(x) (x).begin(), (x).end()
typedef unsigned long long ull;
typedef long long ll;
typedef pair<int, int> pii;

const int R = 'R';
const int B = 'B';
const int Y = 'Y';

const int mod = 1e9 + 7;


struct Node
{
	ll l, r;
	ll lz;
	ll ls, rs;
	ll res;
	ll ok; // 访问该点是否合法

	Node()
	{
		ls = rs = 0;
		l = r = 0;
		lz = 0;
		res = 0;
		ok = 0;
	}
};

vector<ll> arr;
vector<Node> tree;

void pushup(Node& u, Node& x, Node& y)
{
	u.ok = 1;
	u.lz = 0;
	if (!x.ok)
	{
		u.res = y.res;
		u.rs = y.rs;
		u.ls = y.ls;
		u.lz = y.lz;
	}
	else if (!y.ok)
	{
		u.res = x.res;
		u.rs = x.rs;
		u.ls = x.ls;
		u.lz = x.lz;
	}
	else
	{
		u.res = (x.res + y.res) % mod;
		u.ls = x.ls;
		u.rs = y.rs;
		if (x.ls == x.res) u.ls += y.ls, u.ls % mod;
		if (y.rs == y.res and y.ls) u.rs += x.rs, u.rs %= mod;
		if (x.lz) u.lz += x.lz;
		if (y.lz)
		{
			u.res = (y.res + x.res + x.rs * y.lz) % mod;
			if (x.ls == x.res) u.lz += y.lz + (y.lz) * x.lz, u.lz %= mod, u.ls += x.res * y.lz, u.ls %= mod;
			if (y.rs == y.res) u.rs += x.rs * y.lz, u.rs %= mod;
		}
	}
}

void build(ll i, ll l, ll r)
{
	tree[i].l = l;
	tree[i].r = r;
	if (l == r)
	{
		tree[i].ok = 1;
		tree[i].res = 1;
		if (arr[l] == Y)
		{
			tree[i].ls = 1;
			tree[i].rs = 1;
		}
		if (arr[l] == B)
		{
			tree[i].ls = 0;
			tree[i].rs = 1;
		}
		if (arr[l] == R)
		{
			tree[i].lz = 1;
			tree[i].ls = 1;
			tree[i].rs = 1;
		}
		return;
	}
	ll mid = (l + r) / 2;
	build(i << 1, l, mid);
	build(i << 1 | 1, mid + 1, r);
	pushup(tree[i], tree[i << 1], tree[i << 1 | 1]);
}


void modify(ll i, ll l, ll r, ll k)
{
	if (tree[i].l >= l && tree[i].r <= r)
	{
		if (k == Y)
		{
			tree[i].lz = 0;
			tree[i].ls = 1;
			tree[i].rs = 1;
		}
		if (k == B)
		{
			tree[i].lz = 0;
			tree[i].ls = 0;
			tree[i].rs = 1;
		}
		if (k == R)
		{
			tree[i].lz = 1;
			tree[i].ls = 1;
			tree[i].rs = 1;
		}
		return;
	}
	if (tree[i << 1].r >= l)
		modify(i << 1, l, r, k);
	if (tree[i << 1 | 1].l <= r)
		modify(i << 1 | 1, l, r, k);
	pushup(tree[i], tree[i << 1], tree[i << 1 | 1]);
}

Node query(ll i, ll l, ll r)
{
	if (tree[i].l >= l && tree[i].r <= r) return tree[i];
	Node ans, tmp1, tmp2;
	if (tree[i << 1].r >= l) tmp1 = query(i << 1, l, r);
	if (tree[i << 1 | 1].l <= r) tmp2 = query(i << 1 | 1, l, r);
	pushup(ans, tmp1, tmp2);
	return ans;
}

void solve()
{
	int n, m;
	cin >> n >> m;
	string s;
	cin >> s;
	arr.resize(n + 1, 0);
	tree.resize(n << 2);
	for (int i = 1; i <= n; ++i) arr[i] = s[i - 1];
	build(1, 1, n);
	for (int i = 1; i <= m; ++i)
	{
		ll op;
		cin >> op;
		if (op == 1)
		{
			ll a; char b;
			cin >> a >> b;
			int k = b;
			modify(1, a, a, k);
		}
		if (op == 2)
		{
			ll a, b;
			cin >> a >> b;
			Node ans = query(1, a, b);
			cout << ans.res << endl;
		}
	}
}

signed main()
{
	IOS;
	int t = 1;
//	cin >> t;
	while (t--) solve();
	return 0;
}