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 |)\ ...
随机推荐
- 【effective c++】模板与泛型编程
模板元编程:在c++编译器内执行并于编译完成时停止执行 1.了解隐式接口和编译期多态 面向对象编程总是以显式接口(由函数名称.参数类型和返回类型构成)和运行期多态(虚函数)解决问题 模板及泛型编程:对 ...
- 【stl学习笔记】vector
vector是定义于namespace std内的template: namespace std { template<class T, class Allocator = allocator& ...
- Promise编程规范
参考: http://www.cnblogs.com/dojo-lzz/p/4340897.html 闲话promise机制 http://www.cnblogs.com/lvdabao/p/es6 ...
- Android系统改动时间格式为24小时制
1. frameworks/base/packages/SettingsProvider/res/values/defaults.xml 添加<stringname="time_12_ ...
- Qt布局管理器的使用(一)
曾经对Qt的布局管理器掌握的还不清楚,今天特意学习了下.感觉收获还挺大的,特意拿出来和大家分享. 首先.要明确布局管理器的用处,及使我们的界面看起来比較整洁.美化.另外一点就是为了使我们的控件可以更随 ...
- sql跟踪及tkprof使用
简述 在oracle数据库中,awr是关于数据库系统总体的负载情况和运行情况的报告.而当系统负载都显示正常,而client运行某些动作响应非常慢,或者某些终端连接的会话运行缓慢或异常时,就须要用到会话 ...
- UVA 10288 - Coupons(概率递推)
UVA 10288 - Coupons option=com_onlinejudge&Itemid=8&page=show_problem&category=482&p ...
- mac for smartSVN9 (8,9)破解方法 附smartSvn_keygen工具图文
mac for smartSVN9 (8,9)破解方法 附smartSvn_keygen工具 工具文件下载: http://files.cnblogs.com/files/xueshanshan/s ...
- eclipse中将web项目部署到tomcat
eclipse中将web项目部署到tomcat. myeclipse部署WEB项目到tomcat比较方便,但eclipse貌似默认是不会替你将web自动部署到tomcat下的.你Run as该web项 ...
- VS创建Web项目提示配置IISExpress失败
开发服务器VS2013,新建Web项目提示: 打开Web项目提示: 解决方法:控制面板,找到IISExpress,右键 选择修复,解决问题..