码迷,mamicode.com
首页 > 其他好文 > 详细

Codeforces 1076G Array Game 博弈 + 线段树 (看题解)

时间:2019-10-22 22:28:38      阅读:106      评论:0      收藏:0      [点我收藏+]

标签:题解   lse   scanf   int   vector   状态   color   date   为什么   

Array Game

考虑最裸的dp去求胜负态。

dp[ i ] 从后面的 m 个状态转移过来。

我们考虑如何用线段树维护, T[ i ][ mask ] 表示 i 这段区间如果后面接的m位是mask使时开头m位的mask,

对于修改的话只要维护一个反过来的T2就可以了。

感觉是可以想出来的题, 为什么没想出来啊啊啊。

#include<bits/stdc++.h>
#define LL long long
using namespace std;

const int N = (int)2e5 + 7;

int n, m, q, bit, ans, a[N];

int lazy[N << 2];
vector<int> T[N << 2], T2[N << 2];

#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1

inline void pull(int rt) {
    for(int i = 0; i < T[rt].size(); i++) {
        T[rt][i] = T[rt << 1][T[rt << 1 | 1][i]];
        T2[rt][i] = T2[rt << 1][T2[rt << 1 | 1][i]];
    }
}

inline void push(int rt) {
    if(lazy[rt]) {
        swap(T[rt << 1], T2[rt << 1]);
        swap(T[rt << 1 | 1], T2[rt << 1 | 1]);
        lazy[rt << 1] ^= 1;
        lazy[rt << 1 | 1] ^= 1;
        lazy[rt] = 0;
    }
}

void build(int l, int r, int rt) {
    T[rt].resize(1 << m, 0);
    T2[rt].resize(1 << m, 0);
    if(l == r) {
        for(int i = 0; i < T[rt].size(); i++) {
            if(i != ((1 << m) - 1)) T[rt][i] = (i >> 1) | bit, T2[rt][i] = (i >> 1) | bit;
            else if(a[l]) T[rt][i] = (i >> 1), T2[rt][i] = (i >> 1) | bit;
            else T[rt][i] = (i >> 1) | bit, T2[rt][i] = (i >> 1);
        }
        return;
    }
    int mid = l + r >> 1;
    build(lson); build(rson);
    pull(rt);
}

void update(int L, int R, int l, int r, int rt) {
    if(R < l || r < L || R < L) return;
    if(L <= l && r <= R) {
        swap(T[rt], T2[rt]);
        lazy[rt] ^= 1;
        return;
    }
    push(rt);
    int mid = l + r >> 1;
    update(L, R, lson);
    update(L, R, rson);
    pull(rt);
}

void query(int L, int R, int l, int r, int rt) {
    if(R < l || r < L || R < L) return;
    if(L <= l && r <= R) {
        ans = T[rt][ans];
        return;
    }
    push(rt);
    int mid = l + r >> 1;
    query(L, R, rson); query(L, R, lson);
}

int main() {
    scanf("%d%d%d", &n, &m, &q);
    bit = 1 << m - 1;
    for(int i = 1; i <= n; i++) {
        LL x; scanf("%lld", &x);
        a[i] = x & 1;
    }
    build(1, n, 1);
    while(q--) {
        int op;
        scanf("%d", &op);
        if(op == 1) {
            int l, r; LL x;
            scanf("%d%d%lld", &l, &r, &x);
            if(x & 1) update(l, r, 1, n, 1);
        }
        else {
            int l, r;
            scanf("%d%d", &l, &r);
            ans = (1 << m) - 1;
            query(l, r, 1, n, 1);
            if(ans & bit) puts("1");
            else puts("2");
        }
    }
    return 0;
}

/**
**/

 

Codeforces 1076G Array Game 博弈 + 线段树 (看题解)

标签:题解   lse   scanf   int   vector   状态   color   date   为什么   

原文地址:https://www.cnblogs.com/CJLHY/p/11722723.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!