zoukankan      html  css  js  c++  java
  • [洛谷P4735]最大异或和

    题目大意:有一串初始长度为$n$的序列$a$,有两种操作:

    1. $A;x:$在序列末尾加一个数$x$
    2. $Q;l;r;x:$找一个位置$p$,满足$lleqslant pleqslant r$,使得: $a_poplus a_{p+1}oplusdotsoplus a_noplus x$最大,输出最大是多少。

    题解:把序列前缀和,变成$S$,就变成了在$[l-2,r-1]$区间内找一个数$S_p$,使得$S_poplus S_noplus x$最大。可持久化$trie$

    卡点:

    C++ Code:

    #include <cstdio>
    #include <iostream>
    #define M 24
    #define maxn 600010 
    #define N (maxn * (M + 1))
    
    int n, m;
    int __root__[maxn], *root = __root__ + 1, idx;
    int nxt[N][2], V[N], sum;
    void insert(int &rt, int x, int dep) {
    	nxt[++idx][0] = nxt[rt][0], nxt[idx][1] = nxt[rt][1], V[idx] = V[rt] + 1, rt = idx;
    	if (!~dep) return ;
    	int tmp = x >> dep & 1;
    	insert(nxt[rt][tmp], x, dep - 1);
    }
    int query(int x, int L, int R) {
    	int res = 0;
    	for (int i = M; ~i; i--) {
    		int tmp = x >> i & 1;
    		if (V[nxt[R][!tmp]] - V[nxt[L][!tmp]]) L = nxt[L][!tmp], R = nxt[R][!tmp], res |= 1 << i;
    		else L = nxt[L][tmp], R = nxt[R][tmp];
    	}
    	return res;
    }
    int main() {
    	std::ios::sync_with_stdio(false), std::cin.tie(0), std::cout.tie(0);
    	std::cin >> n >> m;
    	insert(root[0], 0, M);
    	for (int i = 1, x; i <= n; i++) {
    		std::cin >> x;
    		insert(root[i] = root[i - 1], sum ^= x, M);
    	}
    	while (m --> 0) {
    		char op;
    		int l, r, x;
    		std::cin >> op >> l;
    		if (op == 'A') {
    			root[n + 1] = root[n];
    			insert(root[++n], sum ^= l, M);
    		} else {
    			std::cin >> r >> x;
    			std::cout << query(x ^ sum, root[l - 2], root[r - 1]) << '
    ';
    		}
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    POJ 1201 Intervals 差分约束
    netframework2.0,asp.net2.0,vs.net 2005
    学习.net第一天
    VS.NET 2003 控件命名规范
    .Net生成共享程序集
    汉字的编码
    [转]用C#实现连接池
    SQL表自连接用法
    一道很好玩的OOP面试题,今天比较有空,所有做了一下
    C#编程规范(2008年4月新版)
  • 原文地址:https://www.cnblogs.com/Memory-of-winter/p/10024652.html
Copyright © 2011-2022 走看看