K. Addition Robot 线段树+锻炼合并思路

题目链接: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;
}
 
发布了74 篇原创文章 · 获赞 29 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/ClonH/article/details/102980109