[Cometoj#3 D]可爱的菜菜子_线段树_差分_线性基
可爱的菜菜子
题目链接:https://cometoj.com/contest/38/problem/D?problem_id=1543
数据范围:略。
题解:
首先,如果第一个操作是单点修改,我们就只需要用线段树维护区间线性基即可。
但是,第一个操作是区间异或,这就很难受了。
区间操作可以怎么转化成单点?差分呗。
将原序列异或差分之后,确实修改变成了单点修改。
查询是否有影响?其实是没有影响的因为相当于整个一个区间的每个数异或上同一个数(前$l - 1$个数的异或和),线性基不受影响。
代码:
#include<bits/stdc++.h>
#define mms(a,n) memset(a,0,sizeof((a)[0])*(n))
#define mmp(a,b,n) memcpy(a,b,sizeof((b)[0])*(n))
#define lowbit(x) ((x)&-(x))
#define pb push_back
#define fi first
#define se second
#define debug(...) fprintf(stderr,__VA_ARGS__)
#define lowbit(x) ((x)&-(x))
#define fo(i,l,r) for(register int i=l,_lim_=r;i<=_lim_;i++)
#define fd(i,r,l) for(register int i=r,_lim_=l;i>=_lim_;i--) using namespace std;
typedef unsigned long long ull;
typedef long long ll;
typedef pair<int,int> pi;
typedef double db;
typedef long double ldb; namespace io{
const int L=(1<<21)+1;
char ibuf[L],*iS,*iT,obuf[L],*oS=obuf,*oT=obuf+L-1,c,st[55];int f,tp;
#ifdef FREOPEN
#define gc() getchar()
#else
#define gc() (iS==iT?(iT=(iS=ibuf)+fread(ibuf,1,L,stdin),(iS==iT?EOF:*iS++)):*iS++)
#endif
inline void flush(){fwrite(obuf,1,oS-obuf,stdout);oS=obuf;}
inline void putc(char x){*oS++=x;if(oS==oT)flush();}
template<class I>
inline void gi(I&x){
for(f=1,c=gc();c<'0'||c>'9';c=gc())if(c=='-')f=-1;
for(x=0;c<='9'&&c>='0';c=gc())x=x*10+(c&15);x*=f;
}
template<class I>
inline void print(I x){
if(!x)putc('0');if(x<0)putc('-'),x=-x;
while(x)st[++tp]=x%10+'0',x/=10;
while(tp)putc(st[tp--]);
}
inline void gs(char*s,int&l){
for(c=gc();c!='_'&&(c<'a'||c>'z');c=gc());
for(l=0;c=='_'||c<='z'&&c>='a';c=gc())s[l++]=c;
}
};
using io::putc;
using io::gi;
using io::gs;
using io::print; const int N=200005,M=32,L=525005; int n,q,a[N],mx;
struct LinearBase{
int a[M],m;
int find(int k){
for(int i=1;i<=m;i++)if((k^a[i])<k)k^=a[i];
return k;
}
int query(int x) {
for(int i = 1; i <= m; ++i) if((x^a[i])>x)
x ^= a[i];
return x;
} void ext(int k){
if(mx>>m){
if(k=find(k)){
int j=1;
while(k<=a[j])j++;
++m;for(int i=m;i>j;i--)a[i]=a[i-1];
a[j]=k;
for(int i=1;i<j;i++)if((k^a[i])<a[i])a[i]^=k;
}
}
}
friend LinearBase operator+(const LinearBase&a,const LinearBase&b){
if((1ll<<a.m)>mx)return a;if((1ll<<b.m)>mx)return b;
LinearBase ret=a;
for(int i=1;i<=b.m;i++)ret.ext(b.a[i]);
return ret;
}
void clear(){while(m)a[m--]=0;}
}seg[L],ans; void build(int x,int l,int r){
if(l==r){
seg[x].ext(a[l]);
return;
}
int mid=(l+r)>>1,ls=x<<1,rs=ls|1;
build(ls,l,mid);build(rs,mid+1,r);
seg[x]=seg[ls]+seg[rs];
} void modify(int x,int l,int r,int p,int k){
if(l==r){
seg[x].a[1]^=k;
mx=max(mx,seg[x].a[1]);
if(!seg[x].a[1])seg[x].m=0;else seg[x].m=1;
return;
}
int mid=(l+r)>>1,ls=x<<1,rs=ls|1;
if(p<=mid)modify(ls,l,mid,p,k);
else modify(rs,mid+1,r,p,k);
seg[x]=seg[ls]+seg[rs];
}
void modify(int x,int l,int r,int p,int q,int k){
if(l==r){
seg[x].a[1]^=k;
mx=max(mx,seg[x].a[1]);
if(!seg[x].a[1])seg[x].m=0;else seg[x].m=1;
return;
}
int mid=(l+r)>>1,ls=x<<1,rs=ls|1;
if(q<=mid)modify(ls,l,mid,p,q,k);
else if(p>mid)modify(rs,mid+1,r,p,q,k);
else modify(ls,l,mid,p,k),modify(rs,mid+1,r,q,k);
seg[x]=seg[ls]+seg[rs];
} LinearBase query(int x,int l,int r,int s,int t){
if(l==s&&r==t)return seg[x];
int mid=(l+r)>>1,ls=x<<1,rs=ls|1;
if(t<=mid)return query(ls,l,mid,s,t);
if(s>mid)return query(rs,mid+1,r,s,t);
if(t-mid>=mid-s+1){
LinearBase w=query(rs,mid+1,r,mid+1,t);
if((1ll<<w.m)>mx)return w;
return w+query(ls,l,mid,s,mid);
}
LinearBase w=query(ls,l,mid,s,mid);
if((1ll<<w.m)>mx)return w;
return w+query(rs,mid+1,r,mid+1,t);
} int sum[N];
void add(int x,int u){while(x<=n)sum[x]^=u,x+=lowbit(x);}
int ask(int x){int r=0;while(x)r^=sum[x],x-=lowbit(x);return r;} int main(){
scanf("%d%d", &n, &q);
for(int i=1,s=0;i<=n;i++) {
scanf("%d", a + i);
add(i, a[i]);
add(i + 1, a[i]);
}
for(int i=n;i>=1;i--)mx=max(mx,a[i]^=a[i-1]);
build(1,1,n);
for(int i=1,op,l,r,k;i<=q;i++){
scanf("%d%d%d%d", &op, &l, &r, &k);
if(op==1){
if(r<n)modify(1,1,n,l,r+1,k);else modify(1,1,n,l,k);
add(l,k);add(r+1,k);
}else{
if(l<r)ans=query(1,1,n,l+1,r);else ans.clear();
ans.ext(ask(l));
printf("%d\n", ans.query(k));
}
}
return 0;
}
[Cometoj#3 D]可爱的菜菜子_线段树_差分_线性基的更多相关文章
- Comet OJ - Contest #3 D可爱的菜菜子(线段树+线性基的合并)
这题其实挺经典的,看到求异或最大,显然想到的是线性基,不过这怎么维护?当然区间有关的东西都可以上线段树,区间修改时记录每个点的修改量k,然后合并线性基时再加入线性基.因为线性基是求一组极大线性无关组, ...
- BZOJ_4636_蒟蒻的数列_线段树+动态开点
BZOJ_4636_蒟蒻的数列_线段树+动态开点 Description 蒟蒻DCrusher不仅喜欢玩扑克,还喜欢研究数列 题目描述 DCrusher有一个数列,初始值均为0,他进行N次操作,每次将 ...
- BZOJ_3252_攻略_线段树+dfs序
BZOJ_3252_攻略_线段树+dfs序 Description 题目简述:树版[k取方格数] 众所周知,桂木桂马是攻略之神,开启攻略之神模式后,他可以同时攻略k部游戏.今天他得到了一款新游戏< ...
- BZOJ_4653_[Noi2016]区间_线段树+离散化+双指针
BZOJ_4653_[Noi2016]区间_线段树+离散化+双指针 Description 在数轴上有 n个闭区间 [l1,r1],[l2,r2],...,[ln,rn].现在要从中选出 m 个区间, ...
- BZOJ_2124_等差子序列_线段树+Hash
BZOJ_2124_等差子序列_线段树+Hash Description 给一个1到N的排列{Ai},询问是否存在1<=p1<p2<p3<p4<p5<…<pL ...
- BZOJ_1826_[JSOI2010]缓存交换 _线段树+贪心
BZOJ_1826_[JSOI2010]缓存交换 _线段树+贪心 Description 在计算机中,CPU只能和高速缓存Cache直接交换数据.当所需的内存单元不在Cache中时,则需要从主存里把数 ...
- BZOJ_1828_[Usaco2010 Mar]balloc 农场分配_线段树
BZOJ_1828_[Usaco2010 Mar]balloc 农场分配_线段树 Description Input 第1行:两个用空格隔开的整数:N和M * 第2行到N+1行:第i+1行表示一个整数 ...
- BZOJ_1798_[AHOI2009]维护序列_线段树
BZOJ_1798_[AHOI2009]维护序列_线段树 题意:老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成. 有长为N的数列,不妨设为a1,a2,…,aN .有如下三种操作形式: ( ...
- BZOJ_3307_雨天的尾巴_线段树合并+树上差分
BZOJ_3307_雨天的尾巴_线段树合并 Description N个点,形成一个树状结构.有M次发放,每次选择两个点x,y 对于x到y的路径上(含x,y)每个点发一袋Z类型的物品.完成 所有发放后 ...
随机推荐
- this绑定问题
this是属性和方法“当前”(运行时)所在的对象.this是函数调用时发生的绑定,它的值只取决于调用位置(箭头函数除外). 函数调用的时候会产生一个执行上下文,this是对这个执行上下文的记录. ❌误 ...
- Oracle 物理结构(五) 文件-在线日志文件
一.什么是在线日志文件 默认情况下redo的块大小是磁盘的扇区大小,通常是512字节,但是现在很多磁盘开始支持4k的扇区,oracle能自动识别并使用4k的大小,但是使用4k的redo block会有 ...
- AtCoder Beginner Contest 128 F - Frog Jump
题意 有一只青蛙,有\(0, 1, \cdots, N - 1\)个荷叶.每个荷叶上有权值\(s_i\). 选定\(A\), \(B\),初始分数为\(0\). 当前位置为\(x\): 对于\(y = ...
- bzoj2688 Green Hackenbush
(没有嘟嘟嘟) 权限题,请各位自己想办法交.不过代码正确性是可以保证的,至于为啥那不能说. 刚学完卡特兰数,就给我这种神题,我除了知道\(n\)个点的不同形态二叉树的数目是卡特兰数外,别的就不会了. ...
- PyTricks-使用namedtuple以及dataclass的方式定义类
from collections import namedtuple from dataclasses import dataclass # 以前简单的类可以使用namedtuple实现. Car = ...
- 感知机和BP神经网络
一.感知机 1.感知机的概念 感知机是用于二分类的线性分类模型,其输入是实例的特征向量,输出是实例的类别,类别取+1和-1二个值,+1代表正类,-1代表负类.感知机对应于输入空间(特征空间)中将实例分 ...
- 修改ssh连上默认目录
vi /etc/passwd ssh连接linux服务器只显示-bash-4.1#不显示路径时,我们只需要修改 ~/.bash_profile文件,如果不存在这个文件,那么新建一个,增加内容 ex ...
- @Value()读取配置文件属性,读出值为null的问题
一.问题描述 自定义一个Filter如下: @Component public class JwtFilter extends GenericFilterBean{ @Value("${jw ...
- 阶段5 3.微服务项目【学成在线】_day03 CMS页面管理开发_17-异常处理-可预知异常处理-异常处理测试
ResultCode有很多的实现类 cmsCode有很多类型的错误异常 pgeService内当CmsPage这个对象为空的时候,异常类型就可以抛出CmsCode里面的错误代码 if(cmsPage1 ...
- Linux下如何安装Nginx
看这就够了 https://segmentfault.com/a/1190000012435644 注意如果是远程浏览器访问是否启动了nginx,出现无法访问 服务器能够启动.访问不了页面 很大可能是 ...