【悬赏关注】分块 + 可持久化 0-1 Trie 样例已过求调
查看原帖
【悬赏关注】分块 + 可持久化 0-1 Trie 样例已过求调
999274
CNS_5t0_0r2楼主2024/10/30 13:23
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 12009,SqrtN = 119,LOGV = 32,S = 2,K = N * LOGV * S;
int n,logn,q,ans;
int a[N],s[N];
struct Trie{
	struct node{
		int ch[S];
		int cnt;
	} t[K];
	int Root[N],node_cnt;
	int new_node(){
		return ++node_cnt;
	}
	void insert(int last_u,int u,int x){
    	for(int i = logn;i >= 0;i--){
    		t[u].cnt = t[last_u].cnt + 1;
    	    int c = (x >> i) & 1;
    	    if(!t[u].ch[c])
    	        t[u].ch[c] = new_node();
    	    t[u].ch[c ^ 1] = t[last_u].ch[c ^ 1];
    	    u = t[u].ch[c];
    	    last_u = t[last_u].ch[c];
 	   }
 	   t[u].cnt = t[last_u].cnt + 1;
	}
	int query(int last_u,int u,int x){
    	int ret = 0;
    	for(int i = logn;i >= 0;i--){
    	    int c = (x >> i) & 1;
    	    if(t[t[u].ch[c ^ 1]].cnt - t[t[last_u].ch[c ^ 1]].cnt){
    	        u = t[u].ch[c ^ 1];
    	        last_u = t[last_u].ch[c ^ 1];
    	        ret = (ret << 1) | 1;
    	    }
    	    else{
    	        u = t[u].ch[c];
    	        last_u = t[last_u].ch[c];
    	        ret <<= 1;
    	    }
    	}
   		return ret;
	}
} trie;
struct block{
	int l,r;
} b[SqrtN];
int block_len,block_cnt;
int belong[N];
void build_block(){
	block_len = block_cnt = (int)sqrt(n);
	for(int i = 1;i <= block_cnt;i++){
		b[i].l = b[i - 1].r + 1;
		b[i].r = b[i].l + block_len - 1;
	}
	b[block_cnt].r = n;
	for(int i = 1;i <= block_cnt;i++)
		for(int j = b[i].l;j <= b[i].r;j++)
			belong[j] = i;
}
int p[SqrtN][SqrtN];//第i~j个块中的最大异或对
int Query(int l,int r,int x){//在区间[l,r]中查询与x构成的最大异或对 
	if(l == 0)
		return max(x,trie.query(trie.Root[l],trie.Root[r],x));
	return trie.query(trie.Root[l - 1],trie.Root[r],x);
}
void init(){
	for(int i = 1;i <= block_cnt;i++){
		int Max = 0;
		for(int j = i;j <= block_cnt;j++){
			for(int k = b[j].l;k <= b[j].r;k++)
				Max = max(Max,Query(b[i].l - 1,b[j].r,a[k]));
			p[i][j] = Max;
		}
	}
}
int query(int l,int r){
	int pos_l = belong[l],pos_r = belong[r];
	int ret = 0;
	if(pos_r == pos_l){
		for(int i = l;i <= r;i++)
			ret = max(ret,Query(l - 1,r,a[i]));
		return ret;
	}
	ret = p[pos_l + 1][pos_r - 1];
	for(int i = l;i <= b[pos_l].r;i++)
		ret = max(ret,Query(l - 1,r,a[i]));
	for(int i = b[pos_r].l;i <= r;i++)
		ret = max(ret,Query(l - 1,r,a[i]));
	return ret;
}
signed main(){
	ios::sync_with_stdio(false);
	cin.tie(0);cout.tie(0);
	cin >> n >> q;
	logn = 30;
	build_block();
	trie.Root[0] = trie.new_node();
	for(int i = 1;i <= n;i++){
		cin >> a[i];
		a[i] ^= a[i - 1];
		trie.Root[i] = trie.new_node();
		trie.insert(trie.Root[i - 1],trie.Root[i],a[i]);
	}
	init();
	int id = 0;
	while(q--){
		id++;
		int l,r;
		cin >> l >> r;
		l = (l + ans) % n + 1;
		r = (r + ans) % n + 1;
		if(l > r)
			swap(l,r);
		ans = query(l,r);
		cout << ans << '\n';
	}
	return 0;
}
2024/10/30 13:23
加载中...