题目链接:https://codeforces.com/problemset/problem/1252/K
留个思路,以后好给学弟学妹出些线段树题。。。
- 1 LL RR. The robot should toggle all the characters of SiSi where L≤i≤RL≤i≤R. Toggling a character means changing it to 'A' if it was previously 'B', or changing it to 'B' if it was previously 'A'.
- 2 LL RR AA BB. The robot should call f(L,R,A,B)f(L,R,A,B) and return two integers as defined in the following pseudocode:
function f(L, R, A, B): FOR i from L to R if S[i] = 'A' A = A + B else B = A + B return (A, B)
You want to implement the robot's expected behavior.
ac 代码:
#include <cstdio>
#include <cstring>
#include <vector>
#include <iterator>
#include <set>
#include <iostream>
#include <vector>
#include <cmath>
#include <algorithm>
#define lc d<<1
#define rc d<<1|1
#define mid ((l+r)>>1)
using namespace std;
const double esp = 1e-6;
typedef long long ll;
namespace T {
const int mx = 4e5+100;
const ll mod = 1e9+7;
char s[mx];
struct tree {
ll a1, a2, b1, b2, la;
tree operator+(const tree &t) {
tree s;
s.la = 0;
s.a1 = (t.a1*a1+t.a2*b1)%mod;
s.a2 = (t.a1*a2+t.a2*b2)%mod;
s.b1 = (t.b1*a1+t.b2*b1)%mod;
s.b2 = (t.b1*a2+t.b2*b2)%mod;
return s;
}
}T[mx];
void pushup(int d) {
T[d] = T[lc]+T[rc];
}
void build(int l, int r, int d) {
if (l == r) {
if (s[l] == 'A') T[d].a1 = 1, T[d].a2 = 1, T[d].b2 = 1;
else T[d].b1 = 1, T[d].b2 = 1, T[d].a1 = 1;
return;
}
build(l, mid, lc);
build(mid+1, r, rc);
pushup(d);
}
void down(int d) {
swap(T[d].a1, T[d].b2);
swap(T[d].a2, T[d].b1);
}
void pushdown(int d) {
if (!T[d].la) return;
down(lc), down(rc);
T[lc].la ^= 1, T[rc].la ^= 1;
T[d].la ^= 1;
}
tree Query(int l, int r, int d, int L, int R) {
if (l == L && r == R)
return T[d];
pushdown(d);
if (mid >= R)
return Query(l, mid, lc, L, R);
if (mid < L)
return Query(mid + 1, r, rc, L, R);
return Query(l, mid, lc, L, mid) + Query(mid + 1, r, rc, mid + 1, R);
}
void update(int l, int r, int d, int L, int R) {
if (l == L && r == R) {
T[d].la ^= 1;
down(d);
return;
}
pushdown(d);
if (mid >= R)
update(l, mid, lc, L, R);
else if (mid < L)
update(mid + 1, r, rc, L, R);
else {
update(l, mid, lc, L, mid);
update(mid + 1, r, rc, mid+1, R);
}
pushup(d);
return;
}
}
using namespace T;
int main() {
int n, m;
ll a, b, c;
int l ,r;
scanf("%d%d", &n, &m);
scanf("%s", s+1);
build(1, n, 1);
for (int i = 0; i < m; ++i) {
scanf("%lld", &a);
if (a == 1) {
scanf("%d%d", &l, &r);
update(1, n, 1, l, r);
}
else {
scanf("%d%d%lld%lld", &l, &r, &a, &b);
tree t = Query(1, n, 1, l, r);
printf("%lld %lld\n", (a*t.a1+b*t.a2)%mod, (a*t.b1+b*t.b2)%mod);
}
}
return 0;
}