Codeforces 1100F(离线 or 在线)
•参考资料
[1]:在线线性基
[2]:离线线性基
[3]:离线线性基
•题意
给你 n 个数,m 次询问;
每次询问给定一个区间 $l,r$,求 $a_{l \cdots r}$ 异或的最大值;
•线段树+线性基
参考了一下资料[1],学会了如何将线性基和线段树结合;
虽然在此题中会 TLE,但是却学到了不少东西;
首先,在建树的时候,将叶节点上的值插入到线性基中;
在回溯的时候,通过 Merge 操作,将 pos 的儿子节点的线性基合并到 pos 的线性基上;
类似于常规线段树中的 pushUp 操作;
此算法可以用来做这道题:洛谷P4839
•Code(线段树TLE版本)
#include<bits/stdc++.h>
using namespace std;
#define ls(x) (x<<1)
#define rs(x) (x<<1|1)
const int maxn=5e5+; int n,q;
int a[maxn];
struct Seg
{
int l,r;
int a[];
int mid(){return l+((r-l)>>);}
void Insert(int x)
{
for(int i=;i >= ;--i)
{
if(x&(<<i))
{
if(!a[i])
{
a[i]=x;
return ;
}
x ^= a[i];
}
}
}
int Max()
{
int ans=;
for(int i=;i >= ;--i)
ans=max(ans,ans^a[i]);
return ans;
}
}seg[maxn<<]; Seg Marge(Seg a,Seg b)
{
Seg tmp=b;
for(int i=;i <= ;++i)
if(a.a[i])
tmp.Insert(a.a[i]);
return tmp;
}
void buildSeg(int l,int r,int pos)
{
seg[pos].l=l;
seg[pos].r=r; if(l == r)
{
seg[pos].Insert(a[l]);
return ;
} int mid=l+((r-l)>>);
buildSeg(l,mid,ls(pos));
buildSeg(mid+,r,rs(pos)); seg[pos]=Marge(seg[ls(pos)],seg[rs(pos)]);
seg[pos].l=l;///此处要注意,因为Marge返回的结果未给l,r赋值
seg[pos].r=r;
}
Seg Query(int l,int r,int pos)
{
if(seg[pos].l == l && seg[pos].r == r)
return seg[pos]; int mid=seg[pos].mid(); if(r <= mid)
return Query(l,r,ls(pos));
else if(l > mid)
return Query(l,r,rs(pos));
else
return Marge(Query(l,mid,ls(pos)),Query(mid+,r,rs(pos)));
}
void Solve()
{
for(int i=;i <= q;++i)
{
int l,r;
scanf("%d%d",&l,&r); Seg ans=Query(l,r,); printf("%d\n",ans.Max());
}
}
int main()
{
// freopen("C:\\Users\\hyacinthLJP\\Desktop\\in&&out\\contest","r",stdin);
scanf("%d",&n);
for(int i=;i <= n;++i)
scanf("%d",a+i);
buildSeg(,n,); scanf("%d",&q);
Solve(); return ;
}
•离线线性基
学会了和线段树结合后,看了看正解 线性基+贪心,果然,看不懂;
放弃了这个解法,找了几篇离线线性基的做法(资料[2],[3]);
大致做法是,将所有询问收集起来,并按照 r 升序排列;
边插入 ai 边判断当前的 i 是否为当前询问的右端点;
插入的时候,记录两个数值 base[ i ] , p[ i ],表示第 p[ i ] 个数 $a_{p_i}$ 在通过 Insert() 操作时,插入的时候插到了 base[ i ] 中;
每次插入第 i 个数 ai 时,优先让高位的 1 用当前的位置来表示,这样可以保证高位的 1 对应的 base 值可以对最大值有贡献;
•Code(离线)
#include<bits/stdc++.h>
using namespace std;
const int maxn=5e5+; int n,m;
int a[maxn];
struct Query
{
int l,r;
int pos;
bool operator < (const Query &obj) const
{
return r < obj.r;
}
}q[maxn];
int base[];
int p[];
int ans[maxn]; void Insert(int pos,int x)
{
for(int i=;i >= ;--i)
{
if(x&(<<i))
{
if(!base[i])
{
base[i]=x;
p[i]=pos;
return ;
}
else if(pos > p[i])///第i位的base[i]优先让p大的表示
{
swap(base[i],x);
swap(p[i],pos);
}
x ^= base[i];
}
}
}
int Max(int k)
{
int l=q[k].l;
int r=q[k].r; int ans=;
///查询时,保证p大的高位base优先考虑
for(int i=;i >= ;--i)
if(p[i] >= l && p[i] <= r)
ans=max(ans,ans^base[i]);
return ans;
}
void Solve()
{
sort(q+,q+m+); int k=;
for(int i=;i <= n;++i)
{
Insert(i,a[i]); while(i == q[k].r)
{ ans[q[k].pos]=Max(k);
k++;
}
} for(int i=;i <= m;++i)
printf("%d\n",ans[i]); return ;
}
int main()
{
// freopen("C:\\Users\\hyacinthLJP\\Desktop\\in&&out\\contest","r",stdin);
scanf("%d",&n);
for(int i=;i <= n;++i)
scanf("%d",a+i); scanf("%d",&m);
for(int i=;i <= m;++i)
{
scanf("%d%d",&q[i].l,&q[i].r);
q[i].pos=i;
} Solve(); return ;
}
•在线线性基
学会了离线的,再看资料[1]的正解代码时,理解起来容易了不少;
•Code(在线)
#include<bits/stdc++.h>
using namespace std;
const int maxn=5e5+; int n,q;
int a[maxn];
int base[maxn][];
int p[maxn][]; void Insert(int pos,int x,int k)
{
for(int i=;i >= ;--i)
{
if(x&(<<i))
{
if(!base[k][i])
{
base[k][i]=x;
p[k][i]=pos;
}
else if(pos > p[k][i])
{
swap(pos,p[k][i]);
swap(x,base[k][i]);
}
x ^= base[k][i];
}
}
}
int Max(int l,int r)
{
int ans=;
for(int i=;i >= ;--i)
if(p[r][i] >= l)
ans=max(ans,ans^base[r][i]);
return ans;
}
void Solve()
{
for(int i=;i <= n;++i)
{
memcpy(base[i],base[i-],sizeof(base[i-]));
memcpy(p[i],p[i-],sizeof(p[i-])); Insert(i,a[i],i);
} while(q--)
{
int l,r;
scanf("%d%d",&l,&r); printf("%d\n",Max(l,r));
}
}
int main()
{
scanf("%d",&n);
for(int i=;i <= n;++i)
scanf("%d",a+i);
scanf("%d",&q); Solve(); return ;
}
Codeforces 1100F(离线 or 在线)的更多相关文章
- CodeForces 1100F Ivan and Burgers
CodeForces题面 Time limit 3000 ms Memory limit 262144 kB Source Codeforces Round #532 (Div. 2) Tags da ...
- CodeForces - 1100F:Ivan and Burgers (线性基&贪心)(离线 在线)
题意:给定N个数,Q次询问,求区间最大异或和. 思路:一开始想的线性基+线段树.单次线性基合并的复杂度为20*20,结合线段树,复杂度为O(NlogN*20*20):显然,超时. 超时代码: #inc ...
- codeforces 1100F Ivan and Burgers 线性基 离线
题目传送门 题意: 给出 n 个数,q次区间查询,每次查询,让你选择任意个下标为 [ l , r ] 区间内的任意数,使这些数异或起来最大,输出最大值. 思路:离线加线性基. 线性基学习博客1 线性基 ...
- CDH集成Kafka,两种方式:离线、在线
1.离线 先下载相应版本的kafka http://archive.cloudera.com/kafka/parcels/ 然后放置相应目录,如下图: 然后直接添加组件即可 2.在线 配置相应的kaf ...
- HDU 2874 Connections between cities(LCA(离线、在线)求树上距离+森林)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2874 题目大意:给出n个点,m条边,q个询问,每次询问(u,v)的最短距离,若(u,v)不连通即不在同 ...
- SPOJ 10628 Count on a tree(Tarjan离线 | RMQ-ST在线求LCA+主席树求树上第K小)
COT - Count on a tree #tree You are given a tree with N nodes.The tree nodes are numbered from 1 to ...
- Linux配置yum源(离线和在线)
配置yum源有2种方法,一种是离线yum源,另外一种是在线yum源. 一.离线yum源,基于安装光盘提供的安装仓库. 建立一个属于仓库文件夹 mkdir /media/zidong cd /media ...
- centos7 离线升级/在线升级操作系统内核
目录 一.前言 二.系统环境 三.系统内核下载网址 四.centos7离线升级系统内核 1.先查看系统环境 2.离线升级系统内核 五.在线升级系统内核 一.前言 CentOS(Community EN ...
- Codeforces 1100F(线性基+贪心)
题目链接 题意 给定序列,$q(1\leq q \leq 100000) $次询问,每次查询给定区间内的最大异或子集. 思路 涉及到最大异或子集肯定从线性基角度入手.将询问按右端点排序后离线处理询问, ...
随机推荐
- 利用JDBC连接Oracle数据库(转)
http://blog.csdn.net/wahaha1_/article/details/8512438 JDBC是Sun公司制定的一个可以用Java语言连接数据库的技术. 一.JDBC基础知识 J ...
- 大数据技术之Oozie
第1章 Oozie简介 Oozie英文翻译为:驯象人.一个基于工作流引擎的开源框架,由Cloudera公司贡献给Apache,提供对Hadoop MapReduce.Pig Jobs的任务调度与协 ...
- 1.2开发文档简读,了解全貌.mp4
- python 类的创建
- 小爬爬5:重点回顾&&移动端数据爬取1
1. ()什么是selenium - 基于浏览器自动化的一个模块 ()在爬虫中为什么使用selenium及其和爬虫之间的关联 - 可以便捷的获取动态加载的数据 - 实现模拟登陆 ()列举常见的sele ...
- Android Binder简介
Android使用Linux的进程管理机制,以进程为单位分配虚拟地址空间.为了安全考虑,Android的不同进程之间是相互隔离的(进程之间被禁止直接交互).如果进程间需要通信,必须通过Android的 ...
- HZOJ trade
强烈谴责$skyh$的没$\Huge 脸$行为. 很经典的可反悔贪心,然而我一直以为是sbdp还一直想着怎么优化…… 正常的贪心肯定是不对的. 但是由于A-C=A-B+B-C, 所以用一个小根堆维护, ...
- jquery解析XML文件实现的省市联动
XML我是直接在网上下载的文件包 拿过来用的 jquery我用的是3.1的 前台页面 <form action="buy.html" method="get&quo ...
- [React Native]访问操作系统剪贴板 Clipboard
我们之前学习了TextInput组件, 有时候我们需要在TextInput组件中复制或者粘贴一些文字. React Native为开发者提供了 Clipboard API,Clipboard 组件可以 ...
- sql表连接 —— join
一.内连接 —— INNER JOIN 内连接是最常见的一种连接,只连接匹配的行. 表1: 表2: 执行查询: select StudentId as 学生编号,StudentName as 姓名,G ...