Xors on Segments Codeforces - 620F
http://codeforces.com/problemset/problem/620/F
此题是莫队,但是不能用一般的莫队做,因为是最优化问题,没有办法在删除元素的时候维护答案。
这题的方法(好像还有个名字叫"回滚莫队“,说明:https://blog.csdn.net/maverickfw/article/details/72988286):
官方题解:http://codeforces.com/blog/entry/22936
设完成一次"加入贡献"的操作的复杂度是O(p)
首先定块大小sz,定每个坐标应该属于的块。
对于左右端点在同一块内的询问,暴力处理即可。每一个询问需要复杂度O(p*sz)
对于其他询问,按左端点所属的块分类。
分类完后,对于同一类的询问,按右端点从小到大排序。对于每一类的询问分开处理。
对于每一类,先把"当前维护区间"的左端点定为 属于该块的坐标 中最靠右的坐标(这样的话,该类询问的左端点都小于等于这个点且离这个点距离不超过sz),右端点定为左端点-1(为了让区间为空)。还要清空当前答案。
对于该类中每一个询问,先照常移动右端点到与询问的右端点相同,然后记下此时的答案,然后把左端点移动到与询问的左端点相同,得到该询问的答案并记录;然后把左端点的移动还原,把答案还原即可(这样就避开了维护答案)
对于每一类,右端点最多有O(n)次移动,而有n/sz类,这一部分复杂度是O(p*n*n/sz);对于每一个询问,额外还要O(p*sz)的复杂度进行左端点的调整
因此,总复杂度是O(p*(n*n/sz+m*sz)),当sz=sqrt(n*n/m)时最小
解决了莫队的问题,还要解决异或最大值维护的问题。这个是用01字典树做的,就不写了。。。看官方题解吧
(大概要支持在01字典树中查询:集合中,对于所有"第二权值"小于等于/大于等于特定值的元素,查询与另一给定值异或的最大值,挺奇怪的)
错误记录:
1.trie没有开垃圾回收,内存不够
2.计算块大小时,没有注意块大小可能变成0
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<set>
#include<queue>
#include<vector>
using namespace std;
int f[];
int n,m,sz,sz1;
//int ttt;
int lft[];
namespace Trie
{
const int l2n=;
int sz[],ch[][],dat[];
multiset<int> ss[];
int x,kkk;
queue<int> qqq;
int getnode()
{
//yttt=max(ttt,int(2000100-qqq.size()));
int t=qqq.front();qqq.pop();
return t;
}
void delnode(int x)
{
qqq.push(x);
}
void deltree(int x)
{
if(!x) return;
deltree(ch[x][]);
deltree(ch[x][]);
ss[x].clear();ch[x][]=ch[x][]=dat[x]=sz[x]=;
delnode(x);
}
void init()
{
int i;
for(i=;i<;i++) qqq.push(i);
lft[]=;
for(i=;i<=l2n;i++) lft[i]=lft[i-]<<;
}
int getdat1(int x) {return x?dat[x]:0x3f3f3f3f;}
void _ins1(int p,int &num)
{
if(!num) num=getnode(),dat[num]=0x3f3f3f3f;
sz[num]++;
if(p>=) _ins1(p-,ch[num][!!(x&lft[p])]),dat[num]=min(getdat1(ch[num][]),getdat1(ch[num][]));
else ss[num].insert(kkk),dat[num]=*ss[num].begin();
}
void ins1(int d,int kk,int &num) {x=d;kkk=kk;_ins1(l2n-,num);}
//ins1维护插入kk的最小值
void _ins2(int p,int &num)
{
if(!num) num=getnode();
sz[num]++;
if(p>=) _ins2(p-,ch[num][!!(x&lft[p])]),dat[num]=max(dat[ch[num][]],dat[ch[num][]]);
else ss[num].insert(kkk),dat[num]=*ss[num].rbegin();
}
void ins2(int d,int kk,int &num) {x=d;kkk=kk;_ins2(l2n-,num);}
//ins2维护插入kk的最大值 void _era1(int p,int &num)
{
sz[num]--;
if(p>=) _era1(p-,ch[num][!!(x&lft[p])]),dat[num]=min(getdat1(ch[num][]),getdat1(ch[num][]));
else ss[num].erase(ss[num].find(kkk)),dat[num]=ss[num].empty()?0x3f3f3f3f:*ss[num].begin();
}
void era1(int d,int kk,int &num) {x=d;kkk=kk;_era1(l2n-,num);}
void _era2(int p,int &num)
{
sz[num]--;
if(p>=) _era2(p-,ch[num][!!(x&lft[p])]),dat[num]=max(dat[ch[num][]],dat[ch[num][]]);
else ss[num].erase(ss[num].find(kkk)),dat[num]=ss[num].empty()?:*ss[num].rbegin();
}
void era2(int d,int kk,int &num) {x=d;kkk=kk;_era2(l2n-,num);} int que1(int x,int kk,int num)//que1查询维护值小于等于kk的数中与x的xor最大值
{
int ans=,i;bool t;
for(i=l2n-;i>=;--i)
{
t=x&lft[i];
if(sz[ch[num][!t]]&&dat[ch[num][!t]]<=kk) ans|=lft[i],num=ch[num][!t];
else num=ch[num][t];
}
return ans;
}
int que2(int x,int kk,int num)//que2查询维护值大于等于kk的数中与x的xor最大值
{
int ans=,i;bool t;
for(i=l2n-;i>=;--i)
{
t=x&lft[i];
if(sz[ch[num][!t]]&&dat[ch[num][!t]]>=kk) ans|=lft[i],num=ch[num][!t];
else num=ch[num][t];
}
return ans;
}
}
using Trie::ins1;using Trie::ins2;
using Trie::era1;using Trie::era2;
using Trie::que1;using Trie::que2;
using Trie::deltree;
struct Q
{
int l,r,num;
Q(){}
Q(int a,int b,int c):l(a),r(b),num(c){}
};
int a[],ans[];
int rt1,rt2;
int anss;
void add1(int p)//加入p的贡献
{
ins1(f[p-],p,rt1);ins2(f[p],p,rt2);
anss=max(anss,que1(f[p],p,rt1));
//printf("a%d\n",f[p]^f[p-1]);
anss=max(anss,que2(f[p-],p,rt2));
}
void del1(int p)
{
era1(f[p-],p,rt1);era2(f[p],p,rt2);
}
vector<Q> q[];
bool cmp(const Q &a,const Q &b) {return a.r<b.r;}
int main()
{
int i,j,j2,l,r,tans;Trie::init();
for(i=;i<=;i++) f[i]=f[i-]^i;
scanf("%d%d",&n,&m);sz=max(,int(sqrt(double(n)/m*n)));sz1=(n-)/sz;
for(i=;i<=n;i++) scanf("%d",&a[i]);
for(i=;i<=m;i++)
{
scanf("%d%d",&l,&r);
if((l-)/sz==(r-)/sz)
{
deltree(rt1);deltree(rt2);
rt1=rt2=anss=;
for(j=l;j<=r;j++) add1(a[j]);
ans[i]=anss;
//printf("a%d %d\n",i,ans[i]);
}
else
q[(l-)/sz].push_back(Q(l,r,i));
}
for(i=;i<=sz1;i++)
{
sort(q[i].begin(),q[i].end(),cmp);
l=(i+)*sz;r=l-;rt1=rt2=anss=;
for(j=;j<q[i].size();j++)
{
while(r<q[i][j].r) add1(a[++r]);
tans=anss;
for(j2=l-;j2>=q[i][j].l;j2--) add1(a[j2]);
ans[q[i][j].num]=anss;
for(j2=l-;j2>=q[i][j].l;j2--) del1(a[j2]);
anss=tans;
}
deltree(rt1);deltree(rt2);
}
for(i=;i<=m;i++) printf("%d\n",ans[i]);
//printf("a%d\n",ttt);
return ;
}
Xors on Segments Codeforces - 620F的更多相关文章
- Codeforces 620F Xors on Segments(暴力+DP)
题目链接 Xors on Segments 预处理出$x[i]$ $=$ $1$ $xor$ $2$ $xor$ $3$ $xor$ $……$ $xor$ $i$ 话说这题$O(n^{2})$居然能过 ...
- Educational Codeforces Round 6 F. Xors on Segments 暴力
F. Xors on Segments 题目连接: http://www.codeforces.com/contest/620/problem/F Description You are given ...
- D - Nested Segments CodeForces - 652D (离散化+树桩数组)
D - Nested Segments CodeForces - 652D You are given n segments on a line. There are no ends of some ...
- codeforces 620F. Xors on Segments
题目链接 定义一种操作f(u, v) = u^u+1^.......^v. (u<=v), 给n个数, q个询问, 每个询问给出一个区间[l, r], 求这个区间里的f(a[i], a[j]) ...
- Segments CodeForces 909B (找规律)
Description You are given an integer N. Consider all possible segments (线段,划分)on the coordinate axis ...
- A - Points and Segments CodeForces - 429E
题解: 方法非常巧妙的一道题 首先考虑要求全部为0怎么做 发现是个欧拉回路的问题(很巧妙) 直接dfs一遍就可以了 而这道题 要求是-1,1,0 我们可以先离散化 完了之后判断每个点被奇数还是偶数条边 ...
- Bipartite Segments CodeForces - 901C (区间二分图计数)
大意: 给定无向图, 无偶环, 每次询问求[l,r]区间内, 有多少子区间是二分图. 无偶环等价于奇环仙人掌森林, 可以直接tarjan求出所有环, 然后就可以预处理出每个点为右端点时的答案. 这样的 ...
- Four Segments CodeForces - 846C
题目 题意:sum(l,r)表示数列a中索引为l到r-1(都包含)的数之和(如果l==r则为0).给出数列a,求合适的delim0, delim1, delim2,使res = sum(0, deli ...
- Educational Codeforces Round 6
620A - Professor GukiZ's Robot 20171122 \(ans=max(\left | x2-x1 \right |,\left | y2-y1 \right |)\ ...
随机推荐
- System表空间大小有10Gb,使用率达到95%,
System表空间大小有10Gb,使用率达到95%,很好奇, 随后执行如下SQL,查看system表空间中使用空间最多的对象 SQL>SELECT * FROM DBA_SEGMENTS T W ...
- django 简易博客开发 5 markdown支持、代码高亮、gravatar头像服务
上一篇博客介绍了comments库使用及ajax支持,现在blog已经具备了基本的功能,但是只能发表文字,不支持富文本编辑.今天我们利用markdown添加富文本支持. markdown语法说明: h ...
- 多硬盘分区管理fdisk
原文:http://blog.fens.me/linux-fdisk/ ---------------------------------------------------------------- ...
- 深入理解 C 指针阅读笔记 -- 第六章
Chapter6.h #ifndef __CHAPTER_6_ #define __CHAPTER_6_ /*<深入理解C指针>学习笔记 -- 第六章*/ typedef struct _ ...
- 读书笔记-HBase in Action-第三部分应用-(2)GIS系统
本章介绍用HBase存储.高效查询地理位置信息. Geohash空间索引 考虑LBS应用中常见的两个问题:1)查找离某地近期的k个地点.2)查找某区域内地点. 假设要用HBase实现高效查找,首先要考 ...
- “var arr = []; ”和 “var arr = {};” 的差别
1.面试题 var arr = []; var arr = {}; 比較上述代码有什么差别? 2.解析 var arr = [];是一个数组对象 var arr = {} ...
- 问题:IIS部署 MVC项目 (autofac) 错误解决
http://www.cnblogs.com/yelaiju/p/3375168.html Could not load file or assembly 'System.Core, Version= ...
- Okapi BM25 (BM stands for Best Matching)
Okapi BM25 - Wikipedia https://en.wikipedia.org/wiki/Okapi_BM25 In information retrieval, Okapi BM25 ...
- 算法4-10:BST平衡二叉树的删除操作
偷懒方法 public void delete(Key key) { insert(key, null); } 这样的方法就是将key相应的值覆盖成null.当读取该键值的时候将会返回null. 这是 ...
- atom及其插件activate-power-mode下载安装
Atom是Github推出的一个文本编辑器,其中包含很多插件可以自行下载安装,其中一个最近比较火的就是插件activate-power-mode,可以实现打字屏振效果, 打字带特效哦,所以最近就尝试安 ...