Port: http://acm.hdu.edu.cn/showproblem.php?pid=6579
Topic:
Two operations
1. Add a number at the end of the sequence
2. Query Interval XOR Maximum
Force Online
Questions:
Violence can be used to maintain an interval linear basis with a data structure, but it can't be overridden.
Greedily maintains the prefix linear base (upper triangle form) of the sequence, and for each linear base, a number appears to the right of the position
Keep words as high as possible, that is, when inserting a new number, record the digits that appear in the corresponding position at the same time.
And if a new number is more to the right than the original number in the position, it will be inserted
Push the original number down.
When maximizing, traverse from high to low if the number on that bit appears at the left end of the query interval
On the right and making the answer larger, it's XOR in the answer.
For each bit of a linear base, the number at a higher position than the linear base it has exclusively passed must appear to its right (no)
Then it will be inserted in that location, so the correctness of the procedure is obvious.
Code:
#include <set> #include <map> #include <cmath> #include <cstdio> #include <string> #include <vector> #include <cstring> #include <iostream> #include <algorithm> using namespace std; typedef long long LL; typedef pair<int, int> pii; typedef unsigned long long uLL; #define ls rt<<1 #define rs rt<<1|1 #define lson l,mid,rt<<1 #define rson mid+1,r,rt<<1|1 #define bug printf("*********\n") #define FIN freopen("input.txt","r",stdin); #define FON freopen("output.txt","w+",stdout); #define IO ios::sync_with_stdio(false),cin.tie(0) #define debug1(x) cout<<"["<<#x<<" "<<(x)<<"]\n" #define debug2(x,y) cout<<"["<<#x<<" "<<(x)<<" "<<#y<<" "<<(y)<<"]\n" #define debug3(x,y,z) cout<<"["<<#x<<" "<<(x)<<" "<<#y<<" "<<(y)<<" "<<#z<<" "<<z<<"]\n" const int maxn = 1e6 + 5; const int INF = 0x3f3f3f3f; const int mod = 1e9 + 7; LL quick_pow(LL x, LL y) { LL ans = 1; while(y) { if(y & 1) { ans = ans * x % mod; } x = x * x % mod; y >>= 1; } return ans; } int f[maxn][32]; int pos[maxn][32]; void add(int x, int i) { int k = i; int tmp; for (int j = 30; j >= 0; --j) f[i][j] = f[i - 1][j], pos[i][j] = pos[i - 1][j]; for (int j = 30; j >= 0; --j) if (x >> j) { if (!f[i][j]) { f[i][j] = x; pos[i][j] = k; break; } else { if (k > pos[i][j]) { tmp = k, k = pos[i][j], pos[i][j] = tmp; tmp = x, x = f[i][j], f[i][j] = tmp; } x ^= f[i][j]; } } } int main() { #ifndef ONLINE_JUDGE FIN #endif int T; scanf("%d", &T); while(T--) { memset(pos, 0, sizeof(pos)); memset(f, 0, sizeof(f)); int n, m; scanf("%d%d", &n, &m); for(int i = 1, x; i <= n; i++) { scanf("%d", &x); add(x, i); } int lastans = 0; while(m--) { int op; int l, r, x; scanf("%d", &op); if(op == 0) { scanf("%d%d", &l, &r); // debug2(l, r); l = (l ^ lastans) % n + 1; r = (r ^ lastans) % n + 1; if(l > r) swap(l, r); int ans = 0; for(int j = 30; j >= 0; --j) { if((ans ^ f[r][j]) > ans && pos[r][j] >= l) { ans ^= f[r][j]; } } printf("%d\n", ans); lastans = ans; } else { scanf("%d", &x); x^=lastans; n++; add(x, n); } } } return 0; }