• BZOJ4103 [Thu Summer Camp 2015]异或运算 【可持久化trie树】


    题目链接

    BZOJ4103

    题解

    一眼看过去是二维结构,实则未然需要树套树之类的数据结构
    区域异或和,就一定是可持久化(trie)

    观察数据,(m)非常大,而(n)(p)比较小,甚至可以每次询问都枚举(x_i)
    所以我们可以考虑对(y_i)(trie),每次询问取出对应区间的(x_i)在对应区间的(trie)树中跑

    多点询问和单点询问时类似的,只不过它们会分开走
    我们只需每次记录每个(x_i)所在的节点
    对于每一层,统计一下能异或出多少(1),如果(le k),每个(x_i)往能异或出(1)的方向走,否则走另一边,并令(k)减去这些数

    复杂度(O(31m + 31qn))

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    #include<map>
    #define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)
    #define REP(i,n) for (int i = 1; i <= (n); i++)
    #define mp(a,b) make_pair<int,int>(a,b)
    #define cls(s) memset(s,0,sizeof(s))
    #define cp pair<int,int>
    #define LL long long int
    using namespace std;
    const int maxn = 300005,B = 30,maxm = 10000005,INF = 1000000000;
    inline int read(){
    	int out = 0,flag = 1; char c = getchar();
    	while (c < 48 || c > 57){if (c == '-') flag = -1; c = getchar();}
    	while (c >= 48 && c <= 57){out = (out << 3) + (out << 1) + c - 48; c = getchar();}
    	return out * flag;
    }
    int bin[50],n,m;
    int a[1005],b[maxn],rt[maxn],cnt;
    int ch[maxm][2],sum[maxm];
    int ins(int x,int v){
    	int u,tmp;
    	u = tmp = ++cnt;
    	for (int i = B; ~i; i--){
    		ch[u][0] = ch[v][0];
    		ch[u][1] = ch[v][1];
    		sum[u] = sum[v] + 1;
    		int t = bin[i] & x; t >>= i;
    		v = ch[v][t];
    		u = ch[u][t] = ++cnt;
    	}
    	sum[u] = sum[v] + 1;
    	return tmp;
    }
    int atu[1005],atv[1005];
    int query(int u,int v,int l,int r,int k){
    	int ans = 0;
    	for (int i = l; i <= r; i++) atu[i] = u,atv[i] = v;
    	for (int i = B; ~i; i--){
    		int cnt = 0;
    		for (int j = l; j <= r; j++){
    			int x = atu[j],y = atv[j],t = bin[i] & a[j]; t >>= i;
    			cnt += sum[ch[x][t ^ 1]] - sum[ch[y][t ^ 1]];
    		}
    		if (cnt >= k){
    			ans += bin[i];
    			for (int j = l; j <= r; j++){
    				int x = atu[j],y = atv[j],t = bin[i] & a[j]; t >>= i;
    				atu[j] = ch[x][t ^ 1];
    				atv[j] = ch[y][t ^ 1];
    			}			
    		}
    		else {
    			k -= cnt;
    			for (int j = l; j <= r; j++){
    				int x = atu[j],y = atv[j],t = bin[i] & a[j]; t >>= i;
    				atu[j] = ch[x][t];
    				atv[j] = ch[y][t];
    			}
    		}
    	}
    	return ans;
    }
    int main(){
    	bin[0] = 1; for (int i = 1; i <= 30; i++) bin[i] = bin[i - 1] << 1;
    	n = read(); m = read();
    	for (int i = 1; i <= n; i++) a[i] = read();
    	for (int i = 1; i <= m; i++){
    		b[i] = read();
    		rt[i] = ins(b[i],rt[i - 1]);
    	}
    	int p = read(),u,d,l,r,k;
    	while (p--){
    		u = read(); d = read(); l = read(); r = read(); k = read();
    		printf("%d
    ",query(rt[r],rt[l - 1],u,d,k));
    	}
    	return 0;
    }
    
    
  • 相关阅读:
    纯CSS3实现3D动画导航,html5 webRTC技术实现免费网页电话拨打
    Base64编解码Android和ios的例子,补充JNI中的例子
    新春寄语
    彩票号码OC呈现
    iOS CFNetwork报错
    Android常用库
    高性能服务端访问设计
    Tomcat的ISO-8859-1
    迅达云s3cmd客户端mac平台部署说明
    Android.os.NetworkOnMainThreadException
  • 原文地址:https://www.cnblogs.com/Mychael/p/9084889.html
Copyright © 2020-2023  润新知