zoukankan      html  css  js  c++  java
  • P4735 最大异或和

    题目链接

    点我跳转

    题目大意

    给定一个非负整数序列 (a),初始长度为 (N)

    (M) 个操作,有以下两种操作类型:

    1、”(A) (X)”:添加操作,表示在序列末尾添加一个数 (X),序列的长度 (N) 增大 (1)
    2、”(Q) (l) (r) (X)”:询问操作,你需要找到一个位置 (p),满足 $ l≤p≤r(,使得:)a_p$ xor (a_{p+1}) xor (…) xor (a_N) xor (x) 最大,输出这个最大值。

    解题思路

    记录 (sum_i) 为前 (i) 个数的前缀和,那么 (a_p) xor (a_{p+1}) xor (…) xor (a_N) xor (X) = (sum_{p-1}) xor (sum_N) xor (X)

    其中 (sum_N) xor (X) 是固定的,那么题目就可以转换为在区间 ([l , r]) 中找到一个 (p) 使得 (sum_{p- 1}) xor ((sum_N) xor (X)) 最大

    即在区间 ([l-1,r-1]) 找到一个 (p) 使得 (sum_{p}) xor ((sum_N) xor (X)) 最大

    然后就是跑可持久化01trie了

    注意特判点 → 当 (r = 1) 时,(r - 1)(0)(root[r- 1] = root[0] = 0) ,故 (root[r - 1]) 的指针无法在字典树上跳动,所以需要特判一下

    AC_Code

    #include<bits/stdc++.h>
    using namespace std;
    const int N = 1e6 + 10;
    int n , m , tot;
    int a[N] , sum[N] , cnt[N * 31] , root[N] , tree[N * 31][2];
    void insert(int id , int s)
    {
    	root[id] = ++ tot;
    	int p = root[id] , q = root[id - 1];
    	for(int i = 31 ; ~i ; i --)
    	{
    		int x =	s >> i & 1;
    		tree[p][x] = ++ tot;
    		tree[p][x ^ 1] = tree[q][x ^ 1];
    		p = tree[p][x] , q = tree[q][x];
    		cnt[p] = cnt[q] + 1;
    	} 
    }
    int query(int l , int r , int s)
    {
    	int res = 0 , p = root[r] , q = root[l - 1];
    	for(int i = 31 ; ~i ; i --)
    	{
    		int x = s >> i & 1;
    		if(cnt[tree[p][x ^ 1]] > cnt[tree[q][x ^ 1]]) 
    		{
    			res += 1LL << i;
    			p = tree[p][x ^ 1] , q = tree[q][x ^ 1];
    		}
    		else p = tree[p][x] , q = tree[q][x];
    	}
    	return res;
    }
    signed main()
    {
    	ios::sync_with_stdio(false);
    	cin.tie(0) , cout.tie(0);
    	cin >> n >> m ;
    	for(int i = 1 ; i <= n ; i ++) cin >> a[i] , sum[i] = sum[i - 1] ^ a[i] , insert(i , sum[i]);
    	while(m --)
    	{
    		char op;
    		cin >> op;
    		if(op == 'A')
    		{
    			cin >> a[++ n];
    			sum[n] = sum[n - 1] ^ a[n];
    			insert(n , sum[n]);
    		}
    		else 
    		{
    			int l , r , x;
    			cin >> l >> r >> x;
    			if(r == 1) 
    			{
    				cout << (sum[n] ^ x) << '
    ';
    				continue ;
    			}
    			cout << query(l - 1 , r - 1 , sum[n] ^ x) << '
    ';
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    SciPy
    时间序列
    bytes 与 str 转换
    tensorflow
    Python3+Cuda+Cudnn+GPU
    TensorFlow models
    saltstack
    docker
    分布式文件系统
    创建RHCS集群环境 创建高可用Apache服务
  • 原文地址:https://www.cnblogs.com/StarRoadTang/p/13735823.html
Copyright © 2011-2022 走看看