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;
    }
    

      

  • 相关阅读:
    C++字节对齐与位域
    使用GDB调试将符号表与程序分离后的可执行文件
    在windows上编译apr库
    使用samba共享文件夹,提供给window访问
    Linux常用命令
    使用VS2015编译xlslib库
    VS资源收藏<持续更新中>
    使用Visual Studio 2017 C++17模块(module)特性
    RMAN中format的参数
    C#的Process类的一些用法
  • 原文地址:https://www.cnblogs.com/Memory-of-winter/p/10024652.html
Copyright © 2011-2022 走看看