题目分析:

一道近似的题目曾经出现在SCOI中,那题可以利用RMQ或者线段树做,这题如果用那种做法时间复杂度会是$log$三次方的。

采用一种类似于整体二分的方法可以解决这道题。

将序列的线段树模型建出来,将每个询问自顶向下找,要么被分到某个区间,要么在当前区间被分成两半。

对于某个区间$[l,r]$,可以找到一个$mid$,求出所有$[i,mid]$和$[mid+1,i]$的线性基。注意到这样的话每个数被插入线性基的次数是树高次,所以求出这些想要的线性基的复杂度是$O(nlog^2n)$。

对于每个被分成两半的区间,可以找到一个$[i,mid]$和$[mid+1,j]$,拼起来,拼起来的复杂度是$O(log^2n)$,每个询问只被拼起来一次,所以时间复杂度是$O((n+q)log^2n)$

代码:

 #include<bits/stdc++.h>
using namespace std; const int maxn = ; int n,a[maxn],q,cal[maxn],ans[maxn];
pair<int,int> qy[maxn];
struct bs{int p[];}sl[maxn],rv[maxn]; void read(){
scanf("%d",&n);
for(int i=;i<=n;i++) scanf("%d",&a[i]);
scanf("%d",&q);
for(int i=;i<=q;i++) scanf("%d%d",&qy[i].first,&qy[i].second);
} int merge(bs alpha,bs beta){
for(int i=;i<;i++){
if(beta.p[i] == ) continue;
for(int j=i;j>=;j--){
if(!(beta.p[i]&(<<j))) continue;
if(alpha.p[j]) beta.p[i] ^= alpha.p[j];
else {alpha.p[j] = beta.p[i];break;}
}
}
int as = ;
for(int i=;i>=;i--)if((as^alpha.p[i]) > as) as ^= alpha.p[i];
return as;
} void solve(int tl,int tr,int l,int r){
int mid = (tl+tr)/;
for(int i=l;i<=r;i++) rv[i] = rv[];
for(int i=mid;i>=tl;i--){
sl[i] = sl[i+]; int hh = a[i];
for(int j=;j>=;j--){
if(!((<<j)&hh)) continue;
if(sl[i].p[j]) hh ^= sl[i].p[j];
else{sl[i].p[j] = hh; break;}
}
}
for(int i=l;i<=r;i++) rv[i] = sl[qy[i].first];
for(int i=tl;i<=mid;i++) sl[i] = sl[];
for(int i=mid+;i<=tr;i++){
sl[i] = sl[i-]; int hh = a[i];
for(int j=;j>=;j--){
if(!((<<j)&hh)) continue;
if(sl[i].p[j]) hh^=sl[i].p[j];
else {sl[i].p[j] = hh; break;}
}
}
for(int i=l;i<=r;i++) ans[cal[i]] = merge(rv[i],sl[qy[i].second]);
for(int i=mid+;i<=tr;i++) sl[i] = sl[];
} void divide(int tl,int tr,int l,int r){
if(l > r) return;
if(tl == tr){for(int i=l;i<=r;i++) ans[cal[i]] = a[tl]; return;}
int mid = (tl+tr)/,num = l-;
for(int i=l;i<=r;i++)
if(qy[i].second<=mid)num++,swap(cal[i],cal[num]),swap(qy[i],qy[num]);
divide(tl,mid,l,num);
int num2 = num;
for(int i=num+;i<=r;i++)
if(qy[i].first>mid)num2++,swap(cal[i],cal[num2]),swap(qy[i],qy[num2]);
divide(mid+,tr,num+,num2);
solve(tl,tr,num2+,r);
} int main(){
read();
for(int i=;i<=q;i++) cal[i] = i;
divide(,n,,q);
for(int i=;i<=q;i++) printf("%d\n",ans[i]);
return ;
}

Codeforces1100F Ivan and Burgers 【整体二分】【线性基】的更多相关文章

  1. Codeforces1100F. Ivan and Burgers(离线+线性基)

    题目链接:传送门 思路: 按查询的右端点离线. 然后从左到右维护线性基. 每个基底更新为最右边的方案,可以让尽量多的查询享受到这个基底. 用ci维护后更新右端点为i的答案. 代码(析构1000ms,别 ...

  2. Ivan and Burgers CodeForces - 1100F (线性基)

    大意: 给定n元素序列, m个询问$(l,r)$, 求$[l,r]$中选出任意数异或后的最大值 线性基沙茶题, 直接线段树暴力维护两个log还是能过的 #include <iostream> ...

  3. Codeforces 1100 F - Ivan and Burgers

    F - Ivan and Burgers 思路:线性基+贪心,保存线性基中每一位的最后一个 代码: #pragma GCC optimize(2) #pragma GCC optimize(3) #p ...

  4. CodeForces - 1100F:Ivan and Burgers (线性基&贪心)(离线 在线)

    题意:给定N个数,Q次询问,求区间最大异或和. 思路:一开始想的线性基+线段树.单次线性基合并的复杂度为20*20,结合线段树,复杂度为O(NlogN*20*20):显然,超时. 超时代码: #inc ...

  5. F. Ivan and Burgers(线性基,离线)

    题目链接:http://codeforces.com/contest/1100/problem/F 题目大意:首先输入n,代表当前有n个数,然后再输入m,代表m次询问,每一次询问是询问区间[l,r], ...

  6. codeforces 1100F Ivan and Burgers 线性基 离线

    题目传送门 题意: 给出 n 个数,q次区间查询,每次查询,让你选择任意个下标为 [ l , r ] 区间内的任意数,使这些数异或起来最大,输出最大值. 思路:离线加线性基. 线性基学习博客1 线性基 ...

  7. 【CF1100F】Ivan and Burgers(线性基,分治)

    题意:给定n个数,每个数为c[i],有q个询问,每次询问从第l个到第r个数字的最大xor和 n,q<=5e5,c[i]<=1e6,时限3s 思路:直接线段树维护区间线性基是3个log,会T ...

  8. Codeforces Round #532 (Div. 2):F. Ivan and Burgers(贪心+异或基)

    F. Ivan and Burgers 题目链接:https://codeforces.com/contest/1100/problem/F 题意: 给出n个数,然后有多个询问,每次回答询问所给出的区 ...

  9. CodeForces 1100F Ivan and Burgers

    CodeForces题面 Time limit 3000 ms Memory limit 262144 kB Source Codeforces Round #532 (Div. 2) Tags da ...

随机推荐

  1. 后端开发者的Vue学习之路(三)

    目录 上节内容回顾 组件 什么是组件 组件注册 全局注册组件 局部注册组件 使用细节 组件注册的命名规范: 组件中只有一个根元素 组件也是一个实例 组件在某些元素中渲染出错 组件间的数据传递 父子组件 ...

  2. float与double

    对数值类型的细节了解在大学里就是一带而过,自己始终也没好好看过.这是在csdn上看到的一篇文章,挺好的,记录下来. https://blog.csdn.net/Demon__Hunter/articl ...

  3. getDimension与getDimensionPixelOffset与getDimensionPixelSize的区别

    getDimension()                       返回float型px值     精确  getDimensionPixelOffset()     返回int型px值     ...

  4. (最详细)小米MIX的Usb调试模式在哪里打开的教程

    当我们使用安卓手机链接pc的时候,或者使用的有些应用比如我们团队营销团队当使用的应用引号精灵,以前老版本就需要开启Usb调试模式下使用,现当新版本不需要了,如果手机没有开启Usb调试模式,pc则没法成 ...

  5. linux下的QT打包方法

    一句话很简单,一个shell脚本搞定,不跟你嘻嘻哈哈 #!/bin/shexe="ThorIceLocker"#存放你的可执行文件的名字des="/home/ninetr ...

  6. .net core 验证 Options 参数

    .net core 中通过 PostConfigure 验证 Options 参数 Intro 在 .net core 中配置项推荐用 Options 来实现,有一些参数可能必须是用由用户来配置,不能 ...

  7. 如何用git上传代码到github详细步骤

    注册账户 这个小菜鸟带着心跳写的第一篇博客! 还请大家多多提点! 想使用github,第一步肯定是要注册github账号,有了账号就是直接登录啦 可以直接打开http://github.com页面注册 ...

  8. Ubuntu下面MySQL的参数文件my.cnf浅析

    前几天刚接手一个MySQL数据,操作系统为Ubuntu 16.04.5 LTS,  数据库版本为5.7.23-0ubuntu0.16.04.1(APT方式安装的MySQL).这个操作系统下的MySQL ...

  9. Docker: 企业级镜像仓库Harbor部署(http)

    Harbor离线安装包下载地址:https://github.com/goharbor/harbor Docker compose(安装harbor需要用到docker compose)下载地址:ht ...

  10. Python爬虫【解析库之pyquery】

    该库跟jQuery的使用方法基本一样  http://pyquery.readthedocs.io/ 官方文档 解析库的安装 pip3 install pyquery 初始化 1.字符串初始化 htm ...