• 【洛谷P4735】最大异或和


    题目大意:给定一个长度为 N 的序列,支持两个操作:在序列末尾添加一个新的数字,查询序列区间 ([l,r]) 内使得 (a_poplus a_{q+1}oplus ... a_Noplus x) 值最大。

    题解:由于是查询区间的最大异或值,可知应该使用可持久化数据结构,再由于是最大异或和,可知采用可持久化 Trie + 前缀和处理。在 Trie 的每个节点上维护一个 size,表示该节点是多少个数字的二进制前缀,查询过程类似于主席树。

    代码如下

    #include <bits/stdc++.h>
    
    using namespace std;
    
    const int maxn = 6e5 + 10;
    
    struct node {
    	node *l, *r;
    	int sz;
    	void pull() {
    		this->sz = 0;
    		if (l != NULL) {
    			this->sz += l->sz;
    		}
    		if (r != NULL) {
    			this->sz += r->sz;
    		}
    	}
    } pool[maxn * 24];
    node *newnode() {
    	static int cnt = 0;
    	return &pool[cnt++];
    }
    node *insert(node *pre, int bit, int val) {
    	node *cur = newnode();
    	if (pre) {
    		*cur = *pre;
    	}
    	if (bit < 0) {
    		cur->sz++;
    		return cur;
    	}
    	if (val >> bit & 1) {
    		cur->r = insert(pre ? pre->r : NULL, bit - 1, val);
    	} else {
    		cur->l = insert(pre ? pre->l : NULL, bit - 1, val);
    	}
    	cur->pull();
    	return cur;
    }
    int query(node *cur, node *pre, int bit, int val) {
    	if (bit < 0) {
    		return 0;
    	}
    	int now = val >> bit & 1;
    	if (now == 0) {
    		int rsz = 0;
    		if (cur && cur->r) rsz += cur->r->sz;
    		if (pre && pre->r) rsz -= pre->r->sz;
    		if (rsz > 0) {
    			return (1 << bit) + query(cur ? cur->r : NULL, pre ? pre->r : NULL, bit - 1, val);
    		} else {
    			return query(cur ? cur->l : NULL, pre ? pre->l : NULL, bit - 1, val);
    		}
    	} else {
    		int lsz = 0;
    		if (cur && cur->l) lsz += cur->l->sz;
    		if (pre && pre->l) lsz -= pre->l->sz;
    		if (lsz > 0) {
    			return (1 << bit) + query(cur ? cur->l : NULL, pre ? pre->l : NULL, bit - 1, val);
    		} else {
    			return query(cur ? cur->r : NULL, pre ? pre->r : NULL, bit - 1, val);
    		}
    	}
    }
    
    int main() {
    	ios::sync_with_stdio(false);
    	cin.tie(0), cout.tie(0);
    	int n, m;
    	cin >> n >> m;
    	vector<int> sum(n + 1);
    	vector<node*> rt(n + 1);
    	rt[0] = insert(NULL, 25, 0);
    	for (int i = 1, x; i <= n; i++) {
    		cin >> x;
    		sum[i] = sum[i - 1] ^ x;
    		rt[i] = insert(rt[i - 1], 25, sum[i]);
    	}
    	while (m--) {
    		string opt;
    		cin >> opt;
    		if (opt[0] == 'A') {
    			int x;
    			cin >> x;
    			int val = sum.back() ^ x;
    			sum.push_back(val);
    			node *cur = insert(rt.back(), 25, val);
    			rt.push_back(cur);
    		} else {
    			int l, r, x;
    			cin >> l >> r >> x;
    			l--, r--;
    			if (l == 0) {
    				cout << query(rt[r], NULL, 25, x ^ sum.back()) << endl;
    			} else {
    				cout << query(rt[r], rt[l - 1], 25, x ^ sum.back()) << endl;
    			}
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    六 .Flask 案例
    五 .Flask 蓝图(文件目录结构)
    四 .Flask 模板 中间件 特殊装饰器 CBV 正则 基础知识(使用)
    七 .Django 模板(template)
    三 .Flask 登录案例认证装饰器 session
    二 .Flask 配置文件 路由 视图 请求 响应 cookie session 闪现 基础知识(使用)
    一 .Flask介绍和基本使用
    一 .微信消息推送
    二 .redis在django中使用
    一 python+redis使用(字典 列表)
  • 原文地址:https://www.cnblogs.com/wzj-xhjbk/p/10405851.html
Copyright © 2020-2023  润新知