[Ynoi2013] 无力回天 NOI2017

首先看到异或,想到能维护异或的东西就那几样(线性基/01trie/数位 dp/FWT),再看到求选任意个数后的异或最大值,线性基无疑了。

这时再看还要维护什么其它信息,区间异或,区间查询,一副线段树维护线性基的样子。但我们知道线性基中的值一旦修改就必须重构,区间修改的时间复杂度不允许,尝试优化这个做法。

可以发现虽然不允许区间修改,但允许单点修改。区间转单点,想到了什么?差分!考虑令 \(b\) 表示原数组的异或差分数组,即 \(b_i=\begin{cases}a_i&\text{若}\ i=1\\a_{i-1}\oplus a_i&\text{若}\ i\not=1\end{cases}\)。反过来,\(a_i\) 为 \(b\) 的异或前缀和。可以发现每次区间异或操作相当于修改 \(b_l\) 和 \(b_{r+1}\) 两个值。

又因为若线性基中的数能表示 \(a_{i-1}\),那么再插入一个 \(b_i\) 一定能够表示 \(a_i\)。所以 \(\{a_l,a_{l+1},a_{l+2},\dots,a_r\}\) 的线性基等价于在 \(\{b_{l+1},b_{l+2},\dots,b_r\}\) 的线性基中插入 \(a_l\) 后的线性基。因此用线段树维护 \(b_l,b_{l+1},b_{l+2},\dots,b_r\) 的线性基,每次修改操作重构 \(l\) 和 \(r+1\) 处的线性基即可。复杂度 \(O(n\log^3n)\)

点击查看代码
#include<bits/stdc++.h>
#define ull unsigned long long
#define ll long long
#define pdi pair<double,int>
#define pii pair<int,int>
#define pb push_back
#define mp make_pair
#define eps 1e-9
using namespace std;
namespace IO{
template<typename T>
inline void read(T &x){
x=0;
int f=1;
char ch=getchar();
while(ch>'9'||ch<'0'){
if(ch=='-'){
f=-1;
}
ch=getchar();
}
while(ch>='0'&&ch<='9'){
x=x*10+(ch-'0');
ch=getchar();
}
x=(f==1?x:-x);
}
template<typename T>
inline void write(T x){
if(x<0){
putchar('-');
x=-x;
}
if(x>=10){
write(x/10);
}
putchar(x%10+'0');
}
template<typename T>
inline void write_endl(T x){
write(x);
putchar('\n');
}
template<typename T>
inline void write_space(T x){
write(x);
putchar(' ');
}
}
using namespace IO;
const int N=5e4+10,Lg=30;
int a[N],b[N],n,q;
struct base{
int p[35];
void ins(int &x){
for(int i=Lg;i>=0;i--){
if(x>>i&1){
if(!p[i]){
p[i]=x;
break;
}
else{
x^=p[i];
}
}
}
}
void clear(){
for(int i=Lg;i>=0;i--){
p[i]=0;
}
}
int query(int mx){
for(int i=Lg;i>=0;i--){
if((mx^p[i])>=mx){
mx^=p[i];
}
}
return mx;
}
};
base merge(base x,base y){
for(int i=Lg;i>=0;i--){
x.ins(y.p[i]);
}
return x;
}
namespace Seg_Tree{
base ans[N<<2];
#define ls(p) p<<1
#define rs(p) p<<1|1
void push_up(int p){
ans[p]=merge(ans[ls(p)],ans[rs(p)]);
}
void build(int p,int l,int r){
if(l==r){
ans[p].ins(b[l]);
return;
}
int mid=(l+r)>>1;
build(ls(p),l,mid);
build(rs(p),mid+1,r);
push_up(p);
}
void update(int p,int l,int r,int pos,int val){
if(l==r){
ans[p].clear();
b[l]^=val;
ans[p].ins(b[l]);
return;
}
int mid=(l+r)>>1;
if(pos<=mid){
update(ls(p),l,mid,pos,val);
}
else{
update(rs(p),mid+1,r,pos,val);
}
push_up(p);
}
base query(int p,int l,int r,int q_l,int q_r){
if(q_l<=l&&r<=q_r){
return ans[p];
}
int mid=(l+r)>>1;
if(q_r<=mid){
return query(ls(p),l,mid,q_l,q_r);
}
if(q_l>mid){
return query(rs(p),mid+1,r,q_l,q_r);
}
return merge(query(ls(p),l,mid,q_l,q_r),query(rs(p),mid+1,r,q_l,q_r));
}
}
namespace Fenwick_Tree{
int ans[N];
int lowbit(int x){
return x&(-x);
}
void update(int pos,int val){
while(pos<=n){
ans[pos]^=val;
pos+=lowbit(pos);
}
}
int query(int pos){
int res=0;
while(pos){
res^=ans[pos];
pos-=lowbit(pos);
}
return res;
}
}
signed main(){
#ifndef ONLINE_JUDGE
freopen("1.in","r",stdin);
freopen("1.out","w",stdout);
#endif
read(n),read(q);
for(int i=1;i<=n;i++){
read(a[i]);
b[i]=a[i]^a[i-1];
}
Seg_Tree::build(1,1,n);
for(int i=1;i<=n;i++){
Fenwick_Tree::update(i,b[i]);
}
while(q--){
int opt,l,r,val;
read(opt),read(l),read(r),read(val);
if(opt==1){
Seg_Tree::update(1,1,n,l,val);
Fenwick_Tree::update(l,val);
if(r<n){
Seg_Tree::update(1,1,n,r+1,val);
Fenwick_Tree::update(r+1,val);
}
}
else{
int x=Fenwick_Tree::query(l);
base y;
y.clear();
if(l!=r){
y=Seg_Tree::query(1,1,n,l+1,r);
}
y.ins(x);
write_endl(y.query(val));
}
}
return 0;
}

[ [Ynoi2013] 无力回天 NOI2017 ] 解题报告的更多相关文章

  1. CH Round #56 - 国庆节欢乐赛解题报告

    最近CH上的比赛很多,在此会全部写出解题报告,与大家交流一下解题方法与技巧. T1 魔幻森林 描述 Cortana来到了一片魔幻森林,这片森林可以被视作一个N*M的矩阵,矩阵中的每个位置上都长着一棵树 ...

  2. 二模13day1解题报告

    二模13day1解题报告 T1.发射站(station) N个发射站,每个发射站有高度hi,发射信号强度vi,每个发射站的信号只会被左和右第一个比他高的收到.现在求收到信号最强的发射站. 我用了时间复 ...

  3. BZOJ 1051 最受欢迎的牛 解题报告

    题目直接摆在这里! 1051: [HAOI2006]受欢迎的牛 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 4438  Solved: 2353[S ...

  4. 习题:codevs 2822 爱在心中 解题报告

    这次的解题报告是有关tarjan算法的一道思维量比较大的题目(真的是原创文章,希望管理员不要再把文章移出首页). 这道题蒟蒻以前做过,但是今天由于要复习tarjan算法,于是就看到codevs分类强联 ...

  5. 习题:codevs 1035 火车停留解题报告

    本蒟蒻又来写解题报告了.这次的题目是codevs 1035 火车停留. 题目大意就是给m个火车的到达时间.停留时间和车载货物的价值,车站有n个车道,而火车停留一次车站就会从车载货物价值中获得1%的利润 ...

  6. 习题: codevs 2492 上帝造题的七分钟2 解题报告

    这道题是受到大犇MagHSK的启发我才得以想出来的,蒟蒻觉得自己的代码跟MagHSK大犇的代码完全比不上,所以这里蒟蒻就套用了MagHSK大犇的代码(大家可以关注下我的博客,友情链接就是大犇MagHS ...

  7. 习题:codevs 1519 过路费 解题报告

    今天拿了这道题目练练手,感觉自己代码能力又增强了不少: 我的思路跟别人可能不一样. 首先我们很容易就能看出,我们需要的边就是最小生成树算法kruskal算法求出来的边,其余的边都可以删掉,于是就有了这 ...

  8. NOIP2016提高组解题报告

    NOIP2016提高组解题报告 更正:NOIP day1 T2天天爱跑步 解题思路见代码. NOIP2016代码整合

  9. LeetCode 解题报告索引

    最近在准备找工作的算法题,刷刷LeetCode,以下是我的解题报告索引,每一题几乎都有详细的说明,供各位码农参考.根据我自己做的进度持续更新中......                        ...

  10. ACM: Just a Hook 解题报告 -线段树

    E - Just a Hook Time Limit:2000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u   D ...

随机推荐

  1. python学习记录(五)-文件操作

    open()参数说明 ''' 参数1:路径 ./当前目录 ../上一级目录 参数2: 基础模式:w r x a w:写入,不存在则创建,存在则打开,清空文件内容,光标指向最前面 r:只读,不存在则报错 ...

  2. python学习记录(四)-意想不到

    计数 from collections import Counter # 计数 res = Counter(['a','b','a','c','a','b']) print(res,type(res) ...

  3. .net core 版本避坑 无法打开项目文件。 无法找到 .NET SDK。请检查确保已安装此项且 global.json 中指定的版本(如有)与所安装的版本相匹配。

    打开项目根目录,输入 dotnet --version  ,查看本机安装的最高版本的sdk: 如果源文件中存在global.json文件,直接打开修改即可: 不存在则接着在1步骤后输入: dotnet ...

  4. redis单机搭建

    1.获取redis wget http://download.redis.io/releases/redis-6.2.7.tar.gz tar -xvf redis-6.2.7.tar.gz 2.安装 ...

  5. python通过轮子安装第三方库(以Wordcloud为例)

    1.查看python版本 直接输入如下命令: python 执行结果如下: 我们可以直到,本机的python版本为: AMD64bit 3.11版本python 2.下载合适python版本的轮子 下 ...

  6. Android笔记--为活动补充附加信息

    利用资源文件配置字符串 具体实现: 利用元数据传递配置信息 给应用页面注册快捷方式 Label属性,需要定义到strings.xml文件里面去:

  7. 记录一次重置数据库root用户的过程

    服务器的mysql突然连接不上去了,密码也忘记了.只能重新设置密码了 1.使用如下指令打开mysql数据库配置文件(具体的文件路径以实际情况为准) vim /etc/my.cnf在虚拟机中直接输入即可 ...

  8. koa中间件的实现原理

    koa中间件的实现原理如何?先来看一个例子. koa的执行顺序是这样的: const middleware = async function (ctx, next) { console.log(1) ...

  9. 三个经典的MySQL问题

    大家好,今天给大家上3个经典的MySQL问题,希望能对大家有帮助!但是因为笔者计算机水平有限,可能会存在一些错误,烦请指出.斧正!谢谢! 一.在MySQL中INNER JOIN.LEFT JOIN.R ...

  10. VUE零碎小技巧1

    1.回顾 创建项目 vue create myapp 准备 scss 库 修改了页面的主结构 App.vue 构建页面的基本结构 分离页面主结构,创建各个页面组件 views views/home/i ...