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中的会话Cookie&&Session
			
会话技术 会话: 一次会话中包含多次请求和响应. 一次会话:浏览器第一次给服务器资源发送请,会话建立,直到有一方断开为止 功能:在一次会话的范围内的多次请求之间共享数据 方式: 客户端会话技术:coo ...
 - 通过ADB查看当前Activity
			
cmd命令中输入:adb shell dumpsys activity activities 在一连串的输出中找到Runing activities com.android.settings是包名. ...
 - AngularJS学习之旅—AngularJS Select(十)
			
1.AngularJS Select(选择框) AngularJS 可以使用数组或对象创建一个下拉列表选项. ng-option:创建一个下拉列表,列表项通过对象和数组循环输出 eg: <div ...
 - AngularJS学习之旅—AngularJS Http(九)
			
1.AngularJS XMLHttpRequest $http 是 AngularJS 中的一个核心服务,用于读取远程服务器的数据. eg: // 简单的 GET 请求,可以改为 POST $htt ...
 - Server 2008 R2多用户远程桌面连接授权,解决120天过期问题
			
在工作中,我们往往需要远程服务器,经常会遇到以下这两个麻烦事. 一.远程桌面的连接数限制,超出系统就会提示超过连接数. 二.远程桌面连接时,同一个用户不能同时远程2个桌面连接. ----------- ...
 - 如何在 windows server 2008 上面 挂载NFS
			
首先, 你在一台服务器上面配置好NFS 服务器:然后按照一下步骤: mounting the nfs on windows server 2008 r2: open Windows Server 的D ...
 - Kafka集成Kerberos之后如何使用生产者消费者命令
			
1.生产者1.1.准备jaas.conf并添加到环境变量(使用以下方式的其中一种)1.1.1.使用Kinit方式前提是手动kinit 配置内容为: KafkaClient { com.sun.secu ...
 - Linux:Day12(上) 进程
			
内核的功用:进程管理.文件系统.网络功能.内存管理.驱动程序.安全功能 Process:运行中的程序的一个副本. 存在生命周期 Linux内核存储进程信息的固定格式 :task struct 多个任务 ...
 - 利用SQL注入漏洞登录后台
			
所谓SQL注入,就是通过把SQL命令插入到Web表单递交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令,比如先前的很多影视网站泄露VIP会员密码大多就是通过WEB表单递交查询 ...
 - zabbix优化,配合文件,zabbix_get命令
			
一.配置文件优化 server端配置文件添加如下 StartPollers=160 #zabbix_server的进程数 StartPollersUnreacheable=80 #默认情况下,ZABB ...