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 线段树动态维护区间线性基的更多相关文章

  1. Codeforces 587 E. Duff as a Queen

    题目链接:http://codeforces.com/contest/587/problem/E 其实就是线段树维护区间线性基,合并的时候注意一下.复杂度${O(nlog^{3})}$ #includ ...

  2. [Cometoj#3 D]可爱的菜菜子_线段树_差分_线性基

    可爱的菜菜子 题目链接:https://cometoj.com/contest/38/problem/D?problem_id=1543 数据范围:略. 题解: 首先,如果第一个操作是单点修改,我们就 ...

  3. BZOJ4644: 经典傻逼题【线段树分治】【线性基】

    Description 这是一道经典傻逼题,对经典题很熟悉的人也不要激动,希望大家不要傻逼. 考虑一张N个点的带权无向图,点的编号为1到N. 对于图中的任意一个点集 (可以为空或者全集),所有恰好有一 ...

  4. codeforces 652C C. Foe Pairs(尺取法+线段树查询一个区间覆盖线段)

    题目链接: C. Foe Pairs time limit per test 1 second memory limit per test 256 megabytes input standard i ...

  5. 【BZOJ-4184 】 Shallot 线段树按时间分治 + 线性基

    4184: shallot Time Limit: 30 Sec  Memory Limit: 128 MBSubmit: 356  Solved: 180[Submit][Status][Discu ...

  6. BZOJ 2752 [HAOI2012]高速公路(road):线段树【维护区间内子串和】

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2752 题意: 有一个初始全为0的,长度为n的序列a. 有两种操作: (1)C l r v: ...

  7. Codeforces 1063F - String Journey(后缀数组+线段树+dp)

    Codeforces 题面传送门 & 洛谷题面传送门 神仙题,做了我整整 2.5h,写篇题解纪念下逝去的中午 后排膜拜 1 年前就独立切掉此题的 ymx,我在 2021 年的第 5270 个小 ...

  8. 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 ...

  9. HDU 1754 I Hate It(线段树单点替换+区间最值)

    I Hate It [题目链接]I Hate It [题目类型]线段树单点替换+区间最值 &题意: 本题目包含多组测试,请处理到文件结束. 在每个测试的第一行,有两个正整数 N 和 M ( 0 ...

随机推荐

  1. Spring Boot与分布式

    ---恢复内容开始--- 分布式.Dubbo/Zookeeper.Spring Boot/Cloud 一.分布式应用 在分布式系统中,国内常用zookeeper+dubbo组合, 而Spring Bo ...

  2. babel 插件编写

    一.开始 工具链接: 每一个节点都有如下所示的接口(Interface): interface Node { type: string; } 字符串形式的 type 字段表示节点的类型(如: &quo ...

  3. react dnd demo

    target import React ,{ Component } from 'react'; import { DropTarget } from 'react-dnd'; import Item ...

  4. jsp使用

    session.setAttribute("sessionName",Object); 用来设置session值的,sessionName是名称,object是你要保存的对象. s ...

  5. 拆系数FFT

    学习内容:国家集训队2016论文 - 再谈快速傅里叶变换 模板题:http://uoj.ac/problem/34 1.基本介绍 对长度为L的\(A(x),B(x)\)进行DFT,可以利用 \[ \b ...

  6. Re.FFT

    前言 上虽然算是学过了但是实质上还是根本什么都不会 看大佬们的模板去A了模题(手动滑稽) 于是下定决心要理解FFT的代码 一些的证明主要是从算法导论和两位大佬的博客上学的 大佬1  大佬2 在这过程中 ...

  7. 集合源码分析[3]-ArrayList 源码分析

    历史文章: Collection 源码分析 AbstractList 源码分析 介绍 ArrayList是一个数组队列,相当于动态数组,与Java的数组对比,他的容量可以动态改变. 继承关系 Arra ...

  8. (二叉树 递归) leetcode 889. Construct Binary Tree from Preorder and Postorder Traversal

    Return any binary tree that matches the given preorder and postorder traversals. Values in the trave ...

  9. [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [E:\soft\studySoft\tomcat\apache-tomcat-8.5.33\webapp

    问题 启动tomcat,就一直卡在了这里 继续往上查看日志 解决方法:

  10. codeforces-1136 (div2)

    A.读到第i章,就有N - i + 1章还没读. #include <map> #include <set> #include <ctime> #include & ...