CodeForces 587 E.Duff as a Queen 线段树动态维护区间线性基
https://codeforces.com/contest/587/problem/E
一个序列,
1区间异或操作
2查询区间子集异或种类数
题解
解题思路大同小异,都是利用异或的性质进行转化,std和很多网友用的都是差分的思想,用两棵线段树
第一棵维护差分序列上的线性基,第二棵维护原序列的异或区间和,两者同时进行修改
考虑两个序列 $(a,b)(d,e)$,按照std的想法,应该是维护$(0 \^ a,a \^ b)(0 \^ d,d \^ e)$ 然后合并首尾变成$(0 \^ a,a \^ b,b \^ d,d \^ e)$
但由于异或的性质,我们直接每个区间保存下区间左端点原来的信息,
直接先插入两个序列的线性基,然后新头部的异或和即可,也就是$(0 \^a,a \^b,a \^ d,d \^e)$
写起来更加轻松
#include <bits/stdc++.h>
#define endl '\n'
#define ll long long
#define ull unsigned long long
#define fi first
#define se second
#define mp make_pair
#define pii pair<ll,ll>
#define all(x) x.begin(),x.end()
#define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define rep(ii,a,b) for(register int ii=a;ii<=b;++ii)
#define per(ii,a,b) for(register int ii=b;ii>=a;--ii)
#define forn(ii,x) for(int ii=head[x];ii;ii=e[ii].next)
#define show(x) cout<<#x<<"="<<x<<endl
#define show2(x,y) cout<<#x<<"="<<x<<" "<<#y<<"="<<y<<endl
#define show3(x,y,z) cout<<#x<<"="<<x<<" "<<#y<<"="<<y<<" "<<#z<<"="<<z<<endl
#define show4(w,x,y,z) cout<<#w<<"="<<w<<" "<<#x<<"="<<x<<" "<<#y<<"="<<y<<" "<<#z<<"="<<z<<endl
#define show5(v,w,x,y,z) cout<<#v<<" "<<v<<" "<<#w<<"="<<w<<" "<<#x<<"="<<x<<" "<<#y<<"="<<y<<" "<<#z<<"="<<z<<endl
#define showa(a,b) cout<<#a<<'['<<b<<"]="<<a[b]<<endl
using namespace std;
const int maxn=2e5+10,maxm=2e5+10;
const int INF=0x3f3f3f3f;
const ll mod=1e9+7;
const double PI=acos(-1.0);
//heads
int casn,n,m,k;
class segtree{public:
#define nd node[now]
#define ndl node[now<<1]
#define ndr node[now<<1|1]
struct segnode{
int l,r,flag,val;
int d[32];
inline void init(){val=flag=0;memset(d,0,sizeof d);}
inline void insert(ll x){
for(register int i=30;x&&i>=0;--i)
if(x&(1ll<<i)){
if(!d[i]) {d[i]=x;return;}
else x^=d[i];
}
}
int count(){int ans=0;per(i,0,30) if(d[i])ans++; return ans;}
void update(int x){val^=x;flag^=x;}
}node[maxn<<2|3];
inline segnode marge(segnode &a,segnode b)const {
segnode ans;ans.init();
per(i,0,30) ans.insert(a.d[i]),ans.insert(b.d[i]);
ans.insert(a.val^b.val);
ans.val=a.val;
ans.l=a.l,ans.r=b.r;
return ans;
}
inline void down(int now){
if(nd.flag){
ndl.update(nd.flag);ndr.update(nd.flag);
nd.flag=0;
}
}
void maketree(int s,int t,int now=1){
nd.l=s,nd.r=t;nd.init();
if(s==t) {cin>>nd.val;return ;}
maketree(s,(s+t)/2,now<<1);
maketree((s+t)/2+1,t,now<<1|1);
nd=marge(ndl,ndr);
}
void update(int s,int t,int x,int now=1){
if(s<=nd.l&&t>=nd.r) {nd.update(x);return;}
down(now);
if(s<=ndl.r) update(s,t,x,now<<1);
if(t>ndl.r) update(s,t,x,now<<1|1);
nd=marge(ndl,ndr);
}
segnode query(int s,int t,int now=1){
if(s<=nd.l&&t>=nd.r) {
if(s==nd.l) {
segnode x;x.init();
return marge(x,nd);
}else return nd;
}
down(now);
segnode ans;ans.init();
if(s<=ndl.r) ans=marge(ans,query(s,t,now<<1));
if(t>ndl.r) ans=marge(ans,query(s,t,now<<1|1));
nd=marge(ndl,ndr);
return ans;
}
}tree;
int main() {
IO;
cin>>n>>m;
register int a,b,c,d;
tree.maketree(1,n);
while(m--){
cin>>a>>b>>c;
if(a==1){
cin>>d;tree.update(b,c,d);
}else cout<<(1<<tree.query(b,c).count())<<endl;
}
}
CodeForces 587 E.Duff as a Queen 线段树动态维护区间线性基的更多相关文章
- Codeforces 587 E. Duff as a Queen
题目链接:http://codeforces.com/contest/587/problem/E 其实就是线段树维护区间线性基,合并的时候注意一下.复杂度${O(nlog^{3})}$ #includ ...
- [Cometoj#3 D]可爱的菜菜子_线段树_差分_线性基
可爱的菜菜子 题目链接:https://cometoj.com/contest/38/problem/D?problem_id=1543 数据范围:略. 题解: 首先,如果第一个操作是单点修改,我们就 ...
- BZOJ4644: 经典傻逼题【线段树分治】【线性基】
Description 这是一道经典傻逼题,对经典题很熟悉的人也不要激动,希望大家不要傻逼. 考虑一张N个点的带权无向图,点的编号为1到N. 对于图中的任意一个点集 (可以为空或者全集),所有恰好有一 ...
- codeforces 652C C. Foe Pairs(尺取法+线段树查询一个区间覆盖线段)
题目链接: C. Foe Pairs time limit per test 1 second memory limit per test 256 megabytes input standard i ...
- 【BZOJ-4184 】 Shallot 线段树按时间分治 + 线性基
4184: shallot Time Limit: 30 Sec Memory Limit: 128 MBSubmit: 356 Solved: 180[Submit][Status][Discu ...
- BZOJ 2752 [HAOI2012]高速公路(road):线段树【维护区间内子串和】
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2752 题意: 有一个初始全为0的,长度为n的序列a. 有两种操作: (1)C l r v: ...
- Codeforces 1063F - String Journey(后缀数组+线段树+dp)
Codeforces 题面传送门 & 洛谷题面传送门 神仙题,做了我整整 2.5h,写篇题解纪念下逝去的中午 后排膜拜 1 年前就独立切掉此题的 ymx,我在 2021 年的第 5270 个小 ...
- codeforces 629D D. Babaei and Birthday Cake (线段树+dp)
D. Babaei and Birthday Cake time limit per test 2 seconds memory limit per test 256 megabytes input ...
- HDU 1754 I Hate It(线段树单点替换+区间最值)
I Hate It [题目链接]I Hate It [题目类型]线段树单点替换+区间最值 &题意: 本题目包含多组测试,请处理到文件结束. 在每个测试的第一行,有两个正整数 N 和 M ( 0 ...
随机推荐
- 搭建SpringMVC+Hibernate
1.首先加入相关的jar包,配置web.xml文件,如下: <?xml version="1.0" encoding="UTF-8"?> <w ...
- [转帖]优化IMPDP/EXPDP导入导出速度
优化IMPDP/EXPDP导入导出速度 https://www.2cto.com/database/201308/238176.html 一年半没太学习数据库了.. 其实这个parallel 的参数一 ...
- Ubuntu 16.04 RabbitMq 安装与运行(安装篇)
Ubuntu 16.04 RabbitMq 安装与运行(安装篇) 2018年08月15日 15:05:24 我跟吴彦祖四六开 阅读数:1966 前言 目前公司用阿里云 + redis 的方式实现的 ...
- 关于ES6
一.变量声明const和let 变量提升:在ES6之前,我们都是用var关键字声明变量.无论声明在何处,都会被视为声明在函数的最顶部(不在函数内即在全局作用域的最顶部).这就是函数变量提升例如: fu ...
- Luogu3732 [HAOI2017] 供给侧改革 【后缀数组】【线段树】【乱搞】
题目分析: 这道题我是乱搞的,因为他说$01$串是随机的. 那么我们可以猜测能够让LCP变大的地方很少.求出后缀数组之后可能让LCP变大的地方就等价于从大到小往height里动态加点同时维护这个点左右 ...
- v-for 循环element-ui菜单
vue 使用了element-ui的菜单组件, 这个组件的el-menu-item项上,有一个属性index,值是字符串类型, 在使用v-for的index时,它是一个数值型,所以如果直接写index ...
- consul 剔除node_exporter的脚本
#!/bin/bash clear echo "node_exporter注销工具" read -p "请输入要踢掉的节点IP,如果有多个IP,请使用英文格式 ',' 隔 ...
- python学习day22 面向对象(四) 约束&反射
1.栈与队列 栈:类似弹夹,先进后出 队列:类似水管,先进先出 class Stack(object): """ 先进后出 """ def ...
- C++ STL的一些操作
priority_queue 最常用的当然是在dij的时候. #include <queue> struct node { int x, dis; bool operator < ( ...
- 【实用Windows双系统一键备份还原工具】Winclone Pro for Mac
[简介] 今天和大家分享最新的 Winclone Pro 7.3.3 Mac 版本,这是一款Mac上强大易用的Windows分区备份还原工具,类似于Windows上的一键Ghost,能够将 PC 上的 ...