[BZOJ 4184]shallot

http://www.lydsy.com/JudgeOnline/problem.php?id=4184
將一個元素入隊和出隊看成時間軸上的一個區間。
每次進行區間覆蓋,不用打標記,dfs時向下傳遞即可

#include <bits/stdc++.h>
#define maxn 500010
using namespace std;

int n;
int a[maxn];

void read(int& num){
    num = 0; char ch = getchar();
    for(; ch < '!'; ch = getchar());
    bool flag = 0; if(ch == '-'){flag = 1; ch = getchar();}
    for(; ch > '!'; ch = getchar())
        num = (num << 3) + (num << 1) + (ch ^ 48);
    if(flag) num = -num;
}

struct Node{
    int l, r;
    vector<int> d;
}t[maxn << 2];

struct Point{
    int a[31];
    Point(){memset(a, 0, sizeof a);}
    int& operator[](const int& k){return a[31];}
    void Insert(int c){
        for(int i = 30; i >= 0; i --){
            if(c >> i & 1){
                if(a[i])c ^= a[i];
                else {a[i] = c; return;}
            }
        }
    }
    int ask(){
        int now = 0;
        for(int i = 30; i >= 0; i --)
            if((now ^ a[i]) > now)
                now ^= a[i];
        return now;
    }
};

#define lc id<<1
#define rc id<<1|1
void build(int id, int l, int r){
    t[id].l = l, t[id].r = r;
    if(l == r)return;
    int mid = l + r >> 1;
    build(lc, l, mid);
    build(rc, mid+1, r);
}

set<pair<int, int> >S;


void update(int id, int l, int r, int val){
    if(t[id].l == l && r == t[id].r){
        t[id].d.push_back(val);
        return;
    }
    int mid = t[id].l + t[id].r >> 1;
    if(r <= mid)update(lc, l, r, val);
    else if(l > mid)update(rc, l, r, val);
    else{
        update(lc, l, mid, val);
        update(rc, mid+1, r, val);
    }
}

void dfs(int id, Point c){
    for(int i = 0; i < t[id].d.size(); i ++)
        c.Insert(t[id].d[i]);
    if(t[id].l == t[id].r){printf("%d\n", c.ask()); return;}
    dfs(lc, c);
    dfs(rc, c);
}

int main(){
    read(n);
    for(int i = 1; i <= n; i ++)
        read(a[i]);
    build(1, 1, n);
    for(int i = 1; i <= n; i ++){
        if(a[i] > 0)S.insert(make_pair(a[i], i));
        else{
            pair<int, int> q = *S.lower_bound(make_pair(-a[i], 0));
            S.erase(q); update(1, q.second, i-1, -a[i]);
        }
    }
    set<pair<int, int> > :: iterator i;
    for(i = S.begin(); i != S.end(); i ++)
        update(1, (*i).second, n, (*i).first);
    dfs(1, Point());
    return 0;
}

關於set

lower_bound(val): 返回容器中第一個值【大於或等於】val的元素的iterator位置。
upper_bound(val): 返回容器中第一個值【大於】val的元素的iterator位置。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章