2022牛客寒假算法基础集训营1 B.炸鸡块君与FIFA22 线段树

2022牛客寒假算法基础集训营1 B.炸鸡块君与FIFA22 线段树,第1张

2022牛客寒假算法基础集训营1 B.炸鸡块君与FIFA22 线段树 思路

主要针对” 3 3 3的整倍数下一局不扣分“限制条件找思路。考虑维护三棵线段树,第一颗线段树表示取模为 0 0 0时后对应分数 *** 作,第二三棵类推。

然后只需要进行一个建树和一个单点查询的 *** 作:注意在push_up的时候,合并左右区间的 *** 作时,对右区间需要额外考虑左区间对分数的影响,也就是算出左区间影响后的分数再取对应 *** 作。
另外,再查询时也需要考虑左区间加入后对右区间的影响。

Accepted Code
#include 
using namespace std;

const int N = 2e5 + 10;
int tree[N << 2][3];
char a[N];

struct node{ int v[3]; node(int a, int b, int c){ v[0] = a, v[1] = b, v[2] = c; }};

inline void push_up(int rt){ 
    for(int i = 0; i < 3; i++) 
        tree[rt][i] = tree[rt << 1][i] + tree[rt << 1 | 1][(i + tree[rt << 1][i]) % 3]; 
}

void build(int rt, int l, int r){
    if(l == r){
        if(a[l] == 'W') tree[rt][0] = tree[rt][1] = tree[rt][2] = 1;
        else if(a[l] == 'L') tree[rt][0] = 0, tree[rt][1] = tree[rt][2] = -1;
        else tree[rt][0] = tree[rt][1] = tree[rt][2] = 0;
        return;
    }
    int mid = l + r >> 1;
    build(rt << 1, l, mid), build(rt << 1 | 1, mid + 1, r);
    push_up(rt);
}

node query(int rt, int l, int r, int L, int R){
    if(l >= L && r <= R) return node{ tree[rt][0], tree[rt][1], tree[rt][2] };
    int mid = l + r >> 1;
    if(mid >= R) return query(rt << 1, l, mid, L, R);
    else if(mid < L) return query(rt << 1 | 1, mid + 1, r, L, R);
    else{
        auto ll = query(rt << 1, l, mid, L, R), rr = query(rt << 1 | 1, mid + 1, r, L, R);
        node res(0, 0, 0);
        
        for(int i = 1; i < 3; i++)
        	res.v[i] = ll.v[i] + rr.v[(i + ll.v[i]) % 3];
        return res;
    }
}

inline void solve(){
    int n = 0, q = 0; cin >> n >> q >> a + 1;
    build(1, 1, n);
    while(q--){
        int l, r, s; cin >> l >> r >> s;
        cout << query(1, 1, n, l, r).v[s % 3] + s << endl;
    }
}

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

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5713754.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存