首页 > 其他分享 >256. 最大异或和

256. 最大异或和

时间:2024-03-11 21:37:17浏览次数:26  
标签:最大 int max tr pos 异或 now 256 id

可持久化字典树

#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <string>
#include <cmath>
#define For(i, j, n) for(int i = j ; i <= n ; ++i)
using namespace std;

const int N = 6e5 + 5, M = N * 24;

int n, m, a[N], idx, tr[M][2], root[N], max_id[M];

void insert(int ver, int now, int last, int k)
{
    if(k < 0)
    {
        max_id[now] = ver;
        return;
    }
    int v = a[ver] >> k & 1;
    if(last)
        tr[now][v ^ 1] = tr[last][v ^ 1];
    tr[now][v] = ++idx;
    insert(ver, tr[now][v], tr[last][v], k - 1);
    max_id[now] = max(max_id[tr[now][0]], max_id[tr[now][1]]);
}

int query(int left, int right, int x)
{
    int pos = root[right];
    for(int k = 23; k >= 0; k--)
    {
        int v = x >> k & 1;
        if(max_id[tr[pos][v ^ 1]] >= left)
            pos = tr[pos][v ^ 1];
        else
            pos = tr[pos][v];
    }
    return x ^ a[max_id[pos]];
}

int main()
{
    scanf("%d%d", &n, &m);
    root[0] = ++idx;
    max_id[0] = -1;
    insert(0, idx, 0, 23);
    for(int i = 1; i <= n; i++)
    {
        scanf("%d", &a[i]);
        a[i] ^= a[i - 1];
        root[i] = ++idx;
        insert(i, root[i], root[i - 1], 23);
    }
    char op[2];
    int l, r, x;
    while(m--)
    {
        scanf("%s", op);
        if(*op == 'A')
        {
            n++;
            scanf("%d", &a[n]);
            root[n] = ++idx;
            a[n] ^= a[n - 1];
            insert(n, root[n], root[n - 1], 23);
        }
        else
        {
            scanf("%d%d%d", &l, &r, &x);
            printf("%d\n", query(l - 1, r - 1, a[n] ^ x));
        }
    }
    return 0;
}

要注意max_id[0]要设置为-1,或者在query中,if里再判断一下目标节点是否是空节点;

否则面对l=1的询问时,很容易就会跳到空节点上,导致答案偏小。

标签:最大,int,max,tr,pos,异或,now,256,id
From: https://www.cnblogs.com/smartljy/p/18067103

相关文章

  • 【刷题笔记】LeetCode-53 最大子数组和
    题目:给你一个整数数组nums,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。示例1:输入:nums=[-2,1,-3,4,-1,2,1,-5,4]输出:6解释:连续子数组 [4,-1,2,1]的和最大,为 6。示例2:输入:nums=[1]输出:1示例3:输入:nums=[5,4,-1,7,8]输出:23......
  • 批处理 检测 并修改系统屏保时间和密码最大过期时间_批处理设置屏保时间-CSDN博客
    批处理检测并修改系统屏保时间和密码最大过期时间_批处理设置屏保时间-CSDN博客 @echooffsecedit/export/cfgc:\security-check-log\temp.txtfind/i"MaximumPasswordAge"c:\security-check-log\temp.txt|find/i"=">c:\security-check-log\temp2.txtregquery......
  • POJ--3258 River Hopscotch(二分搜索/最大化最小值)
    记录10:232023-3-11http://poj.org/problem?id=3259二分法查找最大的可能解,检查x是否符合条件(当前这个位置上的值-前上一个选取位置的值>=x)注意的点:使用了[begin,end)的左闭右开区间,所以结果要begin-1,end要从L+1开始算点击查看代码intL,N,M;introcks[5......
  • 1005. K 次取反后最大化的数组和c
    intlargestSumAfterKNegations(int*nums,intnumsSize,intk){intt[201]={0};intsum=0;for(inti=0;i<numsSize;i++){t[100+nums[i]]++;sum+=nums[i];}while(k>0){for(inti=0;i<201;i++){......
  • 53. 最大子数组和c
    intmax(inti,intj){if(i>j)returni;returnj;}intmaxSubArray(int*nums,intnumsSize){if(numsSize==1)returnnums[0];int*dp=(int*)malloc(sizeof(int)*numsSize);//从0到i,以nums[i]结尾的最大连续字串dp[0]=nums[0];intx=dp[0];......
  • abc160E 吃苹果能得到的最大美味度
    有A个红苹果,美味度分别为p[i];有B个青苹果,美味度分别为q[i];另外还有C个无色苹果,美味度分别为r[i],无色苹果在吃之前可以涂成红色或青色。现在要吃X个红苹果和Y个青苹果,求能吃到的最大美味度。1<=X<=A<=1E5;1<=Y<=B<=1E5;1<=C<=1E5;1<=p[i],q[i],r[i]<=1E9反悔贪心,先不考虑无色......
  • abc281D 最大的能被d整除的k数之和
    题面:给定数组A[n],从中取出k个元素,使元素之和为d的倍数。求满足条件的元素之和的最大值。范围:1<=k<=n<=100;1<=d<=100;0<=A[i]<=1E9思路:记dp[i][j][k]表示前i个数里选了j个,并且元素之和除d的余数为k,按选与不选两种情况递推,这里用的刷表法。#include<bits/stdc++.h>usingnam......
  • 2024-03-09:用go语言,我们把无限数量的栈排成一行,按从左到右的次序从 0 开始编号, 每个栈
    2024-03-09:用go语言,我们把无限数量的栈排成一行,按从左到右的次序从0开始编号,每个栈的的最大容量capacity都相同。实现一个叫「餐盘」的类DinnerPlates,DinnerPlates(intcapacity)-给出栈的最大容量capacity,voidpush(intval)将给出的正整数val推入从左往右第一个......
  • 课堂练习 最大值 原题链接+题解
    题目可以去我的洛谷题库看:https://www.luogu.com.cn/problem/U412348(带数据,真难出)题解考虑两种解题方式。由于题目范围较小,可以check+暴力,如果范围大一点,可以check+二分答案。先讲check函数,小学四年级数学书说了,这种问题也被它叫做“铺地砖”问题,计算剪出的正方形数量的方......
  • 代码随想录 第十六天 | ● 104.二叉树的最大深度 559.n叉树的最大深度 ● 111.二叉树
    leetcode:104.二叉树的最大深度-力扣(LeetCode)思路:递归判断每次左右节点的是否存在,存在自然加一,return的1就是这样,判断子节点的左右两端是否有节点,统计有的节点数量,也就是左右的高度classSolution{publicintmaxDepth(TreeNoderoot){//后序遍历if......