HDU 6579-Operation【線性基】

題意:你有兩種操作,0是查詢[l, r] 區間的異或最大值,1是加入一個值並另n+1,m次操作。

思路:這道題強制在線,記錄一下前綴基,在插入的時候維護一個靠右儘可能在高位的區間,每次更新右邊的值。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 50 + 10;
int p[500010][maxn], pos[500010][maxn]; //pos用來記錄位置
int num;

void add(int x, int num)
{
    int now = num;
    for(int i = 31; i >= 0; --i)
    {
        if(x & (1 << i))
        {
            if(!p[num][i]) //如果沒更新過
            {
                p[num][i] = x;
                pos[num][i] = now;
                break;
            }
            else
            {
                if(now > pos[num][i]) //如果更靠右就交換
                {
                    swap(now, pos[num][i]);
                    swap(x, p[num][i]);
                }
            }
            x ^= p[num][i];
        }
    }
}
int query(int l, int r)
{
    int res = 0;
    for(int i = 31; i >= 0; --i)
    {
        if(pos[r][i] >= l) //只考慮其右邊的貢獻
            res = max(res, res ^ p[r][i]);
    }
    return res;
}

int main()
{
    int t;
    scanf("%d", &t);
    while(t--)
    {
        int n, m;
        scanf("%d%d", &n, &m);
        memset(p, 0, sizeof(p));
        memset(pos, 0, sizeof(pos));
        for(int i = 1; i <= n; ++i)
        {
            for(int j = 31; j >= 0; --j)
            {
                p[i][j] = p[i - 1][j];
                pos[i][j] = pos[i - 1][j];
            }
            int x;
            scanf("%d", &x);
            add(x, i);
        }
        int lastans = 0;
        while(m--)
        {
            int op;
            scanf("%d", &op);
            if(op == 0)
            {
                int l, r;
                scanf("%d%d", &l, &r);
                l = (l ^ lastans) % n + 1, r = (r ^ lastans) % n + 1;
                if(l > r)
                    swap(l, r);
                lastans = query(l, r);
                printf("%d\n", lastans);
            }
            else if(op == 1)
            {
                ++n;
                for(int j = 31; j >= 0; --j)
                {
                    p[n][j] = p[n - 1][j];
                    pos[n][j] = pos[n - 1][j];
                }
                int x;
                scanf("%d", &x);
                add(x ^ lastans, n);
            }
        }
    }
    return 0;
}

/*
1
3 3
0 1 2
0 1 1
1 3
0 3 4
*/

 

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