题意 类似超级钢琴,找最优解用可持久化trie. code: #include<bits/stdc++.h> using namespace std; #define re register typedef long long ll; const int maxn=5*1e5+10; int n,m,tot; int root[maxn],last[maxn*40*2]; int trie[maxn*40][2]; ll ans; ll a[maxn],sum[maxn]; struct no…
题目链接: [十二省联考2019]异或粽子 求前$k$大异或区间,可以发现$k$比较小,我们考虑找出每个区间. 为了快速得到一个区间的异或和,将原序列做前缀异或和. 对于每个点作为右端点时,我们维护出与他异或起来最大的左端点并将这组信息用结构体存起来插入堆中. 那么最大值就是堆顶那组(假设右端点为$r$),但考虑到次大值可能出自同一个右端点,所以在弹出堆顶后还需要将以$r$为右端点的次大值插入堆中. 那么如何求出以$r$为右端点的最大值和次大值? 我们对序列每个数为一个版本建可持久化$trie$…
[BZOJ5495][十二省联考2019]异或粽子(主席树,贪心) 题面 BZOJ 洛谷 题解 这不是送分题吗... 转异或前缀和,构建可持久化\(Trie\). 然后拿一个堆维护每次的最大值,每次如果取了一个数,就把它再在\(Trie\)树上查一次新建一个元素丢回堆里就行了. #include<iostream> #include<cstdio> #include<queue> using namespace std; #define ll long long #de…
[十二省联考2019]异或粽子 01trie 链接 luogu 思路 首先求前k大的(xo[i]^xo[j])(i<j). 考场上只想到01trie,不怎么会写可持久,就写了n个01trie,和直接sort一样.. 咳咳,官方题解是. 一个堆维护i为终点,可以取得位置为\([L,R]\)的最大值为val. 每次选最大的,然后将这个点分裂成两个: i为终点,可以取得位置为\([L,x-1]\)的最大值为\(val_1\). i为终点,可以取得位置为\([x+1,R]\)的最大值为\(val_2\)…
传送门:P5283 [十二省联考2019]异或粽子 题目大意: 给一个长度为n的数列,找到异或和为前k大的区间,并求出这些区间的异或和的代数和. QWQ: 考试时想到了前缀异或 想到了对每个数按二进制拆分 最高位取一定比前面所有取优 但是呆住了 没有想到是对前缀异或拆分 对于位运算等操作可以考虑 线性基和trie 因为 ai​ xor aj​=aj​ xor ai 所以吧这种情况算进去就取ans/2 因为 i​=j 时异或为0是最小的 不会影响答案 把各个前缀异或插进数组 询问强制以每个点为前面…
联考Day1T1...一个考场上蠢了只想到\(O(n^2)\)复杂度的数据结构题 题目大意: 求前\(k\)大区间异或和的和 题目思路: 真的就是个sb数据结构题,可持久化01Trie能过(开O2). 对于区间异或和,显然可以处理成两个前缀异或和的异或和,然后做法就非常蠢,把所有前缀异或和插入到可持久化01Trie里面,然后求以每个位置为右端点的最大区间前缀和,放入大根堆维护.然后从堆中取\(k\)次最大,每次取完把对应位置的相对当前的次大插入堆中.复杂度\(O(开O2能过)\)qwq.众所周知…
感觉不是很难的一题,想了0.5h左右(思路歪了,不过想了一个大常数的两只\(\log\)做法233) 然后码+调了1h,除了一个SB的数组开小外基本上也没什么坑点 先讲一个先想到的方法,我们对于这种问题显然可以二分第\(k\)大,然后验证有多少个值小于等于它 然后考虑怎么判断,我们建一棵0/1Trie,然后枚举一个右端点,每次把整个Trie异或上这个点的权值 具体实现的话就是不断向下走的过程,当这一位为\(1\)时交换左右子树即可 然后相当于查小于等于一个数的数个数以及和,直接Trie上节点维护…
前置芝士:可持久化Trie & 堆 类似于超级钢琴,我们用堆维护一个四元组\((st, l, r, pos)\)表示以\(st\)为起点,终点在\([l, r]\)内,里面的最大值的位置为\(pos\) 我们维护一个小根堆(堆顶最大),权值为st-pos的异或和,每一次找出最大的并删掉 所谓删,就是把一个区间从pos处分裂 即:\((st, l, r)->(st, l, pos - 1) (st, pos + 1, r)\) 这样重新维护pos值即可 维护pos值时,我们需要维护区间内与x的…
做前缀异或和,用堆维护一个五元组(x,l,r,p,v),x为区间右端点的值,l~r为区间左端点的范围,p为x在l~r中最大异或和的位置,v为该最大异或和,每次从堆中取出v最大的元素,以p为界将其切成两部分重新扔进堆即可.查询一个值在一个区间中的最大异或和用可持久化trie实现.luogu上T掉了. #include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> #include<…
LOJ 洛谷 考场上都拍上了,8:50才发现我读错了题=-= 两天都读错题...醉惹... \(Solution1\) 先求一遍前缀异或和. 假设左端点是\(i\),那么我们要在\([i,n]\)中找一个\(sum_j\)使得它和\(sum_{i-1}\)异或最大.可以可持久化Trie. 对\(i\in[1,n]\)都求一遍它能得到的最大的异或值,扔到堆里. 每次从堆里找出值最大的,假设是\(x\),与\(sum_{x-1}\)异或得到最大值的数是\(sum_y\),那么之后就不能选\(sum_…