[bzoj4184]shallot【線段樹】【線性基】

【題目鏈接】
  https://www.lydsy.com/JudgeOnline/problem.php?id=4184
【題解】
  以時間爲下標建立線段樹,每個數有一個存在時間區間,掛在對應線段樹節點上。詢問時維護一個線性基,dfs這顆線段樹,在葉節點查詢。
  時間複雜度O(31NlogN)
【代碼】

/* - - - - - - - - - - - - - - -
    User :      VanishD
    problem :   [bzoj4184]
    Points :    segment tree 
- - - - - - - - - - - - - - - */
# include <bits/stdc++.h>
# define    ll      long long
# define    inf     0x3f3f3f3f
# define    N       500010
# define    K       31
using namespace std;
int read(){
    int tmp = 0, fh = 1; char ch = getchar();
    while (ch < '0' || ch > '9'){ if (ch == '-') fh = -1; ch = getchar(); }
    while (ch >= '0' && ch <= '9'){ tmp = tmp * 10 + ch - '0'; ch = getchar(); }
    return tmp * fh;
}
struct Tree{
    int pl, pr;
    vector <int> q;
}T[N * 3];
struct Node{
    int num[K];
    int query(){
        int tmp = 0;
        for (int i = K - 1; i >= 0; i--)
            if ((tmp ^ num[i]) > tmp)
                tmp ^= num[i];
        return tmp;
    }
    void extend(int tmp){
        for (int i = K - 1; i >= 0; i--)
            if ((tmp & (1 << i)) != 0){
                if (num[i] != 0) tmp ^= num[i];
                    else {
                        num[i] = tmp;
                        return;
                    }
            }
    }
}now;
map <int, int> mp;
int place, L, R, ans[N], n, rt;
void extend(int &p, int data, int ql, int qr, int l, int r){
    if (p == 0) p = ++place;
    if (ql == l && qr == r){
        T[p].q.push_back(data);
        return;
    }
    int mid = (l + r) / 2;
    if (mid >= qr) extend(T[p].pl, data, ql, qr, l, mid);
        else if (mid < ql) extend(T[p].pr, data, ql, qr, mid + 1, r);
            else extend(T[p].pl, data, ql, mid, l, mid), extend(T[p].pr, data, mid + 1, qr, mid + 1, r);
}
void query(int p, Node num, int l, int r){
    if (p == 0){
        int tmp = num.query();
        for (int i = l; i <= r; i++)
            ans[i] = tmp;
        return;
    }
    for (unsigned i = 0; i < T[p].q.size(); i++)
        num.extend(T[p].q[i]);
    if (l == r){
        ans[l] = num.query();
    }
    else {
        int mid = (l + r) / 2;
        query(T[p].pl, num, l, mid);
        query(T[p].pr, num, mid + 1, r);
    }
}
int main(){
//  freopen(".in", "r", stdin);
//  freopen(".out", "w", stdout);
    n = read();
    L = 1, R = n;
    for (int i = 1; i <= n; i++){
        int x = read();
        if (x > 0) mp[x] = i;
        else {
            x = -x;
            int l = mp[x], r = i - 1;
            extend(rt, x, l, r, L, R); 
            mp[x] = 0;
        }
    }
    map <int, int> :: iterator it = mp.begin();
    while (it != mp.end()){
        if ((*it).second != 0) extend(rt, (*it).first, (*it).second, n, L, R);
        it++;
    }
    query(rt, now, L, R);
    for (int i = 1; i <= n; i++)
        printf("%d\n", ans[i]);
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章