Codeforces1100F Ivan and Burgers 【整体二分】【线性基】
题目分析:
一道近似的题目曾经出现在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 【整体二分】【线性基】的更多相关文章
- Codeforces1100F. Ivan and Burgers(离线+线性基)
题目链接:传送门 思路: 按查询的右端点离线. 然后从左到右维护线性基. 每个基底更新为最右边的方案,可以让尽量多的查询享受到这个基底. 用ci维护后更新右端点为i的答案. 代码(析构1000ms,别 ...
- Ivan and Burgers CodeForces - 1100F (线性基)
大意: 给定n元素序列, m个询问$(l,r)$, 求$[l,r]$中选出任意数异或后的最大值 线性基沙茶题, 直接线段树暴力维护两个log还是能过的 #include <iostream> ...
- Codeforces 1100 F - Ivan and Burgers
F - Ivan and Burgers 思路:线性基+贪心,保存线性基中每一位的最后一个 代码: #pragma GCC optimize(2) #pragma GCC optimize(3) #p ...
- CodeForces - 1100F:Ivan and Burgers (线性基&贪心)(离线 在线)
题意:给定N个数,Q次询问,求区间最大异或和. 思路:一开始想的线性基+线段树.单次线性基合并的复杂度为20*20,结合线段树,复杂度为O(NlogN*20*20):显然,超时. 超时代码: #inc ...
- F. Ivan and Burgers(线性基,离线)
题目链接:http://codeforces.com/contest/1100/problem/F 题目大意:首先输入n,代表当前有n个数,然后再输入m,代表m次询问,每一次询问是询问区间[l,r], ...
- codeforces 1100F Ivan and Burgers 线性基 离线
题目传送门 题意: 给出 n 个数,q次区间查询,每次查询,让你选择任意个下标为 [ l , r ] 区间内的任意数,使这些数异或起来最大,输出最大值. 思路:离线加线性基. 线性基学习博客1 线性基 ...
- 【CF1100F】Ivan and Burgers(线性基,分治)
题意:给定n个数,每个数为c[i],有q个询问,每次询问从第l个到第r个数字的最大xor和 n,q<=5e5,c[i]<=1e6,时限3s 思路:直接线段树维护区间线性基是3个log,会T ...
- Codeforces Round #532 (Div. 2):F. Ivan and Burgers(贪心+异或基)
F. Ivan and Burgers 题目链接:https://codeforces.com/contest/1100/problem/F 题意: 给出n个数,然后有多个询问,每次回答询问所给出的区 ...
- CodeForces 1100F Ivan and Burgers
CodeForces题面 Time limit 3000 ms Memory limit 262144 kB Source Codeforces Round #532 (Div. 2) Tags da ...
随机推荐
- java 线程方法 ---- join()
class MyThread2 implements Runnable{ @Override public void run() { for (int i = 0; i < 5; i++){ S ...
- 华为防火墙USG6000V使用总结
问题1.ge 1/0/0 的ip地址 20.0.0.2 ,从直连的对端20.0.0.1 无法ping. 但是从防火墙ping对端却是可以ping通? 原因: 华为新一代的防火墙,默认情况下,只有0口是 ...
- Android ScrollView和ListView滑动冲突解决记录
private int mLastX; private int mLastY; public View.OnTouchListener onTouchListener = new View.OnTou ...
- virtual table for class
虚函数表 说起虚函数,相信你我都可以自然而然的想到“多态”,因为多态的实现就依赖于虚函数的继承和重写(覆盖).那么,class又或者是object是如何来管理虚函数的呢?你我又会想到虚函数表. 虚函数 ...
- PJProject(2.6) 工程介绍
pjlib pjlib\build\pjlib.vcproj pjlib_test pjlib\build\pjlib_test.vcproj pjsip_core pjsip\build\pjsip ...
- ORACLE中如何查找定位表最后DML操作的时间小结
在Oracle数据库中,如何查找,定位一张表最后一次的DML操作的时间呢? 方式有三种,不过都有一些局限性,下面简单的解析.总结一下. 1:使用ORA_ROWSCN伪列获取表最后的DML时间 ORA_ ...
- 宇宙第一开发工具:vs2019 开发Python
1.初步认识 现在人工智能逐步进入人们的视野,人工智能开发也越来越火. 而python语言,被作为大数据库开发的首选语言之一~.前一段时间vs2019预览版发布.相信不少小伙伴已经开始使用,vs201 ...
- 对java中的equals()方法的总结
Java的基础学习总结--equals方法 一,等于方法介绍 1.1.通过下面的例子掌握等于的用法 1 package cn.galc.test; 2 3 public class TestEqual ...
- .NET CORE学习笔记系列(5)——ASP.NET CORE的运行原理解析
一.概述 在ASP.NET Core之前,ASP.NET Framework应用程序由IIS加载.Web应用程序的入口点由InetMgr.exe创建并调用托管,初始化过程中触发HttpApplicat ...
- 1.5 下载和安装VMWare
搭建虚拟环境一般都有两种方法,一种是系统自带的虚拟机,还有一种是下载VMware,Win8和Win10都自带有虚拟机,但是都不是自动开启的,所以我们必须手动开启. 一.Win10开启虚拟机 在命令行输 ...