洛谷 P5607 [Ynoi2013] 无力回天 NOI2017
人生第一道Ynoi,开心
Description
https://www.luogu.com.cn/problem/P5607
Solution
拿到这个题,看了一下,发现询问要求最大异或和,怎么办?
没办法,我只学过线性基,就顺着这个思路硬上吧。
我们开一颗线段树,里面的节点存线性基,那么空间复杂度是\(O(n \log v)\)的
先不管修改操作,那么我们容易分析得到单次查询的复杂度是\(O(\log n \log^2 v)\)
这个复杂度一看就是正解,接着想修改
区间\(\text{xor}\)还得维护线性基???什么鬼???
我们想,区间\(\text{xor}\)在线段树上难以办到,但是单点\(\text{xor}\)很简单
怎么办?
差分啊!!!
但我们怎么差分才能保证正确性呢?
熟知,对于一个数列\(a_n\)
如果我们把它差分,使得\(b_1 = a_1, b_i = a_i \text{xor} a_{i-1} (i>1)\)
那么由线性代数基础知识,数列\(b_n\)的线性基和原数列的线性基是一样的
这启发我们线段树维护差分的线性基,然后再单独维护\(a\),询问时将\(a\)插入线段树查询得到的线性基、
这个\(a\)就很好维护了,直接上线段树或者树状数组维护差分即可
这样,单次修改复杂度为\(O(\log n \log v)\)
Code
#include <cstdio>
#include <iostream>
using namespace std;
const int N = 50010;
int n, m, a[N], b[N], opt, l, r, v;
inline int read() {
int res = 0, flag = 0; char ch = getchar();
for(; !isdigit(ch); ch = getchar()) if(ch == '-') flag = 1;
for(; isdigit(ch); ch = getchar()) res = (res << 1) + (res << 3) + (ch ^ 48);
if(flag) res = ~res + 1;
return res;
}
struct LineBase{
int a[31];
inline void clear() {for(int i = 0; i < 31; ++i) a[i] = 0;}
inline void insert(int x) {
for(int i = 30; i + 1; --i)
if(x & (1 << i))
if(!a[i]) {a[i] = x; break;}
else x ^= a[i];
}
}O;
inline LineBase merge(LineBase x, LineBase y) {
for(int i = 30; i + 1; --i) if(y.a[i]) x.insert(y.a[i]);
return x;
}
struct SegmentTree{
#define lc (k << 1)
#define rc (lc | 1)
#define mid (l + r >> 1)
LineBase tr[N << 2];
inline void update(int k) {tr[k] = merge(tr[lc], tr[rc]);}
inline void build(int k, int l, int r) {
if(l == r) {tr[k].insert(b[l]); return;}
build(lc, l, mid), build(rc, mid + 1, r), update(k);
}
inline void modify(int k, int l, int r, int loc) {
if(l > loc || r < loc) return ;
if(l == r) {tr[k].clear(), tr[k].insert(b[l]); return;}
modify(lc, l, mid, loc), modify(rc, mid + 1, r, loc), update(k);
}
inline LineBase query(int k, int l, int r, int L, int R) {
if(l > R || r < L) return O;
if(L <= l && r <= R) return tr[k];
return merge(query(lc, l, mid, L, R), query(rc, mid + 1, r, L, R));
}
}s;
struct BIT{
#define lowbit(x) (x & -x)
int tr[N];
inline void insert(int x, int v) {for(; x <= n; x += lowbit(x)) tr[x] ^= v;}
inline int query(int x) {int res = 0; for(; x; x -= lowbit(x)) res = res ^ tr[x]; return res;}
}bit;
inline void out(int x) {
int flag = 0;
for(int i = 30; i + 1; --i)
if(flag) printf("%d",((x & (1 << i)) > 0));
else if(x & (1 << i)) printf("1"), flag = 1;
if(!flag) printf("0");
}
int main() {
n = read(), m = read();
for(int i = 1; i <= n; ++i) a[i] = read(), b[i] = a[i] ^ a[i - 1], bit.insert(i, b[i]); b[n + 1] = a[n];
s.build(1, 1, n + 1);
for(int i = 1; i <= m; ++i) {
opt = read(), l = read(), r = read(), v = read();
if(opt == 1) {
b[l] ^= v, b[r + 1] ^= v;
bit.insert(l, v), bit.insert(r + 1, v);
s.modify(1, 1, n + 1, l), s.modify(1, 1, n + 1, r + 1);
}
else {
LineBase ans = s.query(1, 1, n + 1, l + 1, r);
ans.insert(bit.query(l));
for(int j = 30; j + 1; --j) if((ans.a[j] ^ v) > v) v ^= ans.a[j];
printf("%d\n",v);
}
}
return 0;
}
洛谷 P5607 [Ynoi2013] 无力回天 NOI2017的更多相关文章
- BZOJ4946 & 洛谷3826 & UOJ318:[NOI2017]蔬菜——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=4946 https://www.luogu.org/problemnew/show/P3826 ht ...
- BZOJ4943 & 洛谷3823 & UOJ315:[NOI2017]蚯蚓排队——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=4943 http://uoj.ac/problem/315 https://www.luogu.or ...
- BZOJ4945 & 洛谷3825 & UOJ317:[NOI2017]游戏——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=4945 https://www.luogu.org/problemnew/show/P3825 ht ...
- 洛谷3825 [NOI2017]游戏 2-sat
原文链接http://www.cnblogs.com/zhouzhendong/p/8146041.html 题目传送门 - 洛谷3825 题解 我们考虑到地图中x的个数很少,最多只有8个. 所以我们 ...
- 洛谷P3832 [NOI2017]蚯蚓排队 【链表 + 字符串hash】
题目链接 洛谷P3832 题解 字符串哈希然后丢到hash表里边查询即可 因为\(k \le 50\),1.2操作就暴力维护一下 经复杂度分析会发现直接这样暴力维护是对的 一开始自然溢出WA了,还以为 ...
- 洛谷 P3825 [NOI2017]游戏 【2-SAT+状压】
UOJ和洛谷上能A,bzoj 8ms即WA,现在也不是知道为啥--因为我太弱了 先看数据范围发现d非常小,自然想到了状压. 所以先假装都是只能跑两种车的,这显然就是个2-SAT问题了:对于x场没有hx ...
- 【洛谷3822】[NOI2017] 整数(线段树压位)
题目: 洛谷 3822 分析: 直接按题意模拟,完了. 将每次加 / 减拆成不超过 \(32\) 个对单独一位的加 / 减. 考虑给一个二进制位(下称「当前位」)加 \(1\) 时,如果这一位本来就是 ...
- 洛谷 P1843 奶牛晒衣服
题目背景 熊大妈决定给每个牛宝宝都穿上可爱的婴儿装 . 于是 , 为牛宝宝洗晒衣服就成了很不爽的事情. 题目描述 熊大妈请你帮助完成这个重任 . 洗完衣服后 , 你就要弄干衣服 . 衣服在自然条件下用 ...
- 洛谷 P2827 BZOJ 4721 UOJ #264 蚯蚓
题目描述 本题中,我们将用符号表示对c向下取整,例如:. 蛐蛐国最近蚯蚓成灾了!隔壁跳蚤国的跳蚤也拿蚯蚓们没办法,蛐蛐国王只好去请神刀手来帮他们消灭蚯蚓. 蛐蛐国里现在共有n只蚯蚓(n为正整数).每只 ...
随机推荐
- 丽泽普及2022交流赛day15 社论
前言 link 太牛逼了,补完我一定放代码 . orz 越看越牛逼 orz . 时间复杂度都是口胡,不要信 . 以下是目录 目录 目录 前言 A 题面 题解 代码 B 题面 题解 代码 C 题面 题解 ...
- YII学习总结5(视图)
<?php namespace app\controllers; use yii\web\Controller; class HelloController extends Controller ...
- 金瓯无缺江河一统|Win10系统基于Docker和Python3搭建并维护统一认证系统OpenLdap
原文转载自「刘悦的技术博客」https://v3u.cn/a_id_180 OpenLdap(Lightweight Directory Access Protocol)是什么?它其实是一个开源的.具 ...
- Java中list集合自定义排序-2022新项目
一.业务场景 为了加快首页数据查询的效率,因此将首页查询的数据大多数都放在了缓存中,包括各种list集合数据.对这些 从缓存中获取的数据做了一个兜底处理,如果从缓存中没有获取到数据,则直接从数据库中去 ...
- SP104 Highways (矩阵树,高斯消元)
矩阵树定理裸题 //#include <iostream> #include <cstdio> #include <cstring> #include <al ...
- 用VS Code搞Qt6:至简窗口部件——QWidget
在正题开始之前,老周照例扯点别的.嗯,咱们扯一下在 VS 2022 下结合 CMake 开发 Qt6 时的环境变量设置问题.在VS Code 中,通够通过 CMake Tools 扩展的配置来设置环境 ...
- oracle 怎么查看用户对应的表空间
oracle 怎么查看用户对应的表空间? 查询用户: 查看数据库里面所有用户,前提是你是有 dba 权限的帐号,如 sys,system: select * from dba_users; 查看你能管 ...
- 给ShardingSphere提了个PR,不知道是不是嫌弃我
说来惭愧,干了 10 来年程序员,还没有给开源做过任何贡献,以前只知道嘎嘎写,出了问题嘎嘎改,从来没想过提个 PR 去修复他,最近碰到个问题,发现挺简单的,就随手提了个 PR 过去. 问题 问题挺简单 ...
- python进阶__用socket封装TCP
想要理解socket协议,点击链接,出门左转 一.TCP 通信的服务器端编程的基本步骤: 服务器端先创建一个 socket 对象. 服务器端 socket 将自己绑定到指定 IP 地址和端口. 服务器 ...
- git revert总结
git revert git revert 是一种创建一次新的commit 来回退某次或某几次commit的一种方式 命令 // 创建一个新的commit,这个commit会删除(下面)commit- ...