loj6100 「2017 山东二轮集训 Day1」第一题
传送门:https://loj.ac/problem/6100
【题解】
我们考虑维护从某个端点开始的最长满足条件的长度,如果知道了这个东西显然我们可以用主席树来对每个节点建棵关于右端点的权值线段树,然后区间修改,标记永久化,询问就可以差分了
考虑如何求出某个端点开始的最长满足条件的长度,也就是某个端点$i$开始,到nxt[i]的这一段都满足异或不减性质。
考虑异或什么时候会导致减法:修改了最高位的时候
我们令s[x][i][j]表示$1 \sim i$个位置,二进制下第j位被当做最高位的时候,被操作了几次,$x$为0或1。0表示原来是1,变成0的次数;1表示原来是0,变成1的次数。
那么我们每次找出最高位就能更新了。
我们还要维护一个前缀异或值来进行操作。
然后我们二分右端点,考虑如何判断区间$[l,r]$是否合法。
对于某一位,如果在$l-1$的时候,前缀异或值为1,那么从$l$开始,相当于没有这个前缀异或值,也就是当修改从0改成1的时候,由于我们是假装他有“1”的前缀异或值,来进行s的操作的,所以s从0改成1相当于实际的1改成0,也就是减小。
同理对于在$l-1$的时候,前缀异或值为0,也进行类似操作判断即可。
那么这个复杂度是$O(logn)$的,因为有log位要判断。
预处理复杂度$O(nlog^2n)$
挺好写的吧。。
# include <stdio.h>
# include <string.h>
# include <iostream>
# include <algorithm> using namespace std; typedef long long ll;
typedef unsigned long long ull;
typedef long double ld; const int M = 2e5 + , N = 1e5 + ;
const int mod = 1e9 + , Max = 5e6 + ; int n, a[N], nxt[N];
int s[][N][], sxor[N];
// 前i个数,第j位为最高位的时候,有多少次从1变成0 (1),以及从0变成1 (0). # define bit(x, i) (((x) >> (i)) & )
# define len(l, r) ((r) - (l) + ) inline bool chk(int l, int r) {
for (int i=; ~i; --i) {
if(bit(sxor[l-], i) && s[][r][i] - s[][l-][i] > ) return false;
if(!bit(sxor[l-], i) && s[][r][i] - s[][l-][i] > ) return false;
}
return true;
} inline bool chk_force(int l, int r) {
int cur, lst; cur = lst = ;
for (int i=l; i<=r; ++i) {
cur = lst ^ a[i];
if(cur < lst) return false;
lst = cur;
}
return true;
} inline int gh(int x) {
for (int i=; ~i; --i)
if(bit(x, i)) return i;
return -;
} inline int gnext(int pos) {
int l=pos, r=n, mid;
while() {
if(r-l <= ) {
for (int i=r; i>=l; --i)
if(chk(pos, i)) return i;
break;
}
mid = l+r>>;
if(chk(pos, mid)) l = mid;
else r = mid;
}
return -;
} int rt[M];
struct CMT {
int ch[Max][], tag[Max], siz;
ll s[Max]; # define ls ch[x][]
# define rs ch[x][] inline void set() {
siz = ;
memset(tag, , sizeof tag);
memset(s, , sizeof s);
} inline void edt(int &x, int y, int l, int r, int L, int R, int d) {
x = ++siz; ch[x][] = ch[y][], ch[x][] = ch[y][];
s[x] = s[y]; tag[x] = tag[y];
if(L == l && r == R) {
tag[x] += d;
return ;
}
s[x] += (ll)d * (R-L+);
int mid = l+r>>;
if(R <= mid) edt(ls, ch[y][], l, mid, L, R, d);
else if(L > mid) edt(rs, ch[y][], mid+, r, L, R, d);
else edt(ls, ch[y][], l, mid, L, mid, d), edt(rs, ch[y][], mid+, r, mid+, R, d);
} inline ll query(int x, int y, int l, int r, int L, int R) {
ll ret = (ll)(tag[y] - tag[x]) * (R-L+);
if(L == l && r == R) return ret + s[y] - s[x];
int mid = l+r>>;
if(R <= mid) return ret + query(ls, ch[y][], l, mid, L, R);
else if(L > mid) return ret + query(rs, ch[y][], mid+, r, L, R);
else return ret + query(ls, ch[y][], l, mid, L, mid) + query(rs, ch[y][], mid+, r, mid+, R);
}
}T; int main() {
cin >> n; sxor[] = ;
for (int i=, h; i<=n; ++i) {
scanf("%d", a+i); sxor[i] = sxor[i-] ^ a[i];
for (int j=; j<=; ++j) s[][i][j] = s[][i-][j], s[][i][j] = s[][i-][j];
h = gh(a[i]);
if(h != -) {
if(bit(sxor[i-], h)) s[][i][h] ++;
else s[][i][h] ++;
}
} for (int i=; i<=n; ++i) nxt[i] = gnext(i); T.set();
for (int i=; i<=n; ++i) T.edt(rt[i], rt[i-], , n, i, nxt[i], ); int Q; cin >> Q;
ll lst = ; int l, r;
while(Q--) {
scanf("%d%d", &l, &r);
l = (l+lst)%n+, r = (r+lst)%n+;
if(l>r) swap(l, r);
lst = T.query(rt[l-], rt[r], , n, l, r);
printf("%lld\n", lst);
lst %= n;
} return ;
}
loj6100 「2017 山东二轮集训 Day1」第一题的更多相关文章
- loj6102 「2017 山东二轮集训 Day1」第三题
传送门:https://loj.ac/problem/6102 [题解] 贴一份zyz在知乎的回答吧 https://www.zhihu.com/question/61218881 其实是经典问题 # ...
- LOJ6102「2017 山东二轮集训 Day1」第三题 【min-max容斥,反演】
题目描述:输入一个大小为\(n\)的集合\(S\),求\(\text{lcm}_{k\in S}f_k\),其中\(f_k\)是第$$个Fibonacci数. 数据范围:\(n\le 5\times ...
- 【LOJ#6066】「2017 山东一轮集训 Day3」第二题(哈希,二分)
[LOJ#6066]「2017 山东一轮集训 Day3」第二题(哈希,二分) 题面 LOJ 题解 要哈希是很显然的,那么就考虑哈希什么... 要找一个东西可以表示一棵树,所以我们找到了括号序列. 那么 ...
- LOJ #6119. 「2017 山东二轮集训 Day7」国王
Description 在某个神奇的大陆上,有一个国家,这片大陆的所有城市间的道路网可以看做是一棵树,每个城市要么是工业城市,要么是农业城市,这个国家的人认为一条路径是 exciting 的,当且仅当 ...
- loj6119 「2017 山东二轮集训 Day7」国王
题目描述 在某个神奇的大陆上,有一个国家,这片大陆的所有城市间的道路网可以看做是一棵树,每个城市要么是工业城市,要么是农业城市,这个国家的人认为一条路径是 exciting 的,当且仅当这条路径上的工 ...
- [LOJ#6066]. 「2017 山东一轮集训 Day3」第二题[二分+括号序列+hash]
题意 题目链接 分析 首先二分,假设二分的答案为 \(mid\),然后考虑利用括号序列来表示树的形态. 点 \(u\) 的 \(k-\) 子树的括号序列表示实际上是刨去了 \(u\) 子树内若干个与 ...
- LOJ6066:「2017 山东一轮集训 Day3」第二题
传送门 二分答案 \(k\),考虑如何 \(hash\) 使得做起来方便 把每个点挂在 \(k+1\) 级祖先上,考虑在祖先上删除 这道题巧妙在于其可以对于 \(dfs\) 序/括号序列 \(hash ...
- LOJ 6060「2017 山东一轮集训 Day1 / SDWC2018 Day1」Set(线性基,贪心)
LOJ 6060「2017 山东一轮集训 Day1 / SDWC2018 Day1」Set $ solution: $ 这一题的重点在于优先级问题,我们应该先保证总和最大,然后再保证某一个最小.于是我 ...
- 【LOJ6077】「2017 山东一轮集训 Day7」逆序对 生成函数+组合数+DP
[LOJ6077]「2017 山东一轮集训 Day7」逆序对 题目描述 给定 n,k ,请求出长度为 n的逆序对数恰好为 k 的排列的个数.答案对 109+7 取模. 对于一个长度为 n 的排列 p ...
随机推荐
- vuex的使用及持久化state的方式详解
vuex的使用及持久化state的方式详解 转载 更新时间:2018年01月23日 09:09:37 作者:baby格鲁特 我要评论 这篇文章主要介绍了vuex的使用及持久化state的方 ...
- Less入门教程
http://www.cnblogs.com/fsjohnhuang/p/4187675.html
- Android 序列化比对
本文转自:https://www.zybuluo.com/linux1s1s/note/91046 注:部分内容有更改 在Android中使用序列化,无非两种途经: Parcelable 和 Seri ...
- (原创)像极了爱情的详解排序二叉树,一秒get
排序二叉树(建立.查找.删除) 二叉树我们已经非常熟悉了,但是除了寻常的储存数据.遍历结构,我们还能用二叉树做什么呢? 我们都知道不同的遍历方式会对相同的树中产生不同的序列结果,排序二叉树就是利用二叉 ...
- LeetCode 36——有效的数独
1. 题目 2. 解答 将数独中数字的 ASCII 码值转化到 0-8 之间作为散列值,建立一个散列表,然后分别逐行.逐列.逐宫(3*3小块)统计每个数字的出现次数,若出现次数大于 1,则数独无效. ...
- eclipse 创建Makefile工程生成多个执行文件
1.创建Makefile工程 2.创建inc src Debug 目录 用于存放头文件源文件 3.编写Makefile 需要在有源文件的目标天剑Makefile文件,如下给出一个生成两个target的 ...
- Week1 Team Homework #1 from Z.XML-对于学长项目《shield star》的思考和看法
试用了一下学长黄杨等人开发的<shield star>游戏. 其实作为一个学弟,我对cocos2d-x引擎还算是比较了解,所以对于这样一款很“典型 ...
- 漫谈单点登录(SSO)
1. 摘要 ( 注意:请仔细看下摘要,留心此文是否是您的菜,若浪费宝贵时间,深感歉意!!!) SSO这一概念由来已久,网络上对应不同场景的成熟SSO解决方案比比皆是,从简单到复杂,各式各样应有尽有!开 ...
- Java使用泛型的困顿
原文有点儿胡说的意味,删了,有空再次更新这篇博文~
- maven release版本重复上传error
A couple things I can think of: user credentials are wrong url to server is wrong user does not have ...