传送门: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」第一题的更多相关文章

  1. loj6102 「2017 山东二轮集训 Day1」第三题

    传送门:https://loj.ac/problem/6102 [题解] 贴一份zyz在知乎的回答吧 https://www.zhihu.com/question/61218881 其实是经典问题 # ...

  2. LOJ6102「2017 山东二轮集训 Day1」第三题 【min-max容斥,反演】

    题目描述:输入一个大小为\(n\)的集合\(S\),求\(\text{lcm}_{k\in S}f_k\),其中\(f_k\)是第$$个Fibonacci数. 数据范围:\(n\le 5\times ...

  3. 【LOJ#6066】「2017 山东一轮集训 Day3」第二题(哈希,二分)

    [LOJ#6066]「2017 山东一轮集训 Day3」第二题(哈希,二分) 题面 LOJ 题解 要哈希是很显然的,那么就考虑哈希什么... 要找一个东西可以表示一棵树,所以我们找到了括号序列. 那么 ...

  4. LOJ #6119. 「2017 山东二轮集训 Day7」国王

    Description 在某个神奇的大陆上,有一个国家,这片大陆的所有城市间的道路网可以看做是一棵树,每个城市要么是工业城市,要么是农业城市,这个国家的人认为一条路径是 exciting 的,当且仅当 ...

  5. loj6119 「2017 山东二轮集训 Day7」国王

    题目描述 在某个神奇的大陆上,有一个国家,这片大陆的所有城市间的道路网可以看做是一棵树,每个城市要么是工业城市,要么是农业城市,这个国家的人认为一条路径是 exciting 的,当且仅当这条路径上的工 ...

  6. [LOJ#6066]. 「2017 山东一轮集训 Day3」第二题[二分+括号序列+hash]

    题意 题目链接 分析 首先二分,假设二分的答案为 \(mid\),然后考虑利用括号序列来表示树的形态. 点 \(u\) 的 \(k-\) 子树的括号序列表示实际上是刨去了 \(u\) 子树内若干个与 ...

  7. LOJ6066:「2017 山东一轮集训 Day3」第二题

    传送门 二分答案 \(k\),考虑如何 \(hash\) 使得做起来方便 把每个点挂在 \(k+1\) 级祖先上,考虑在祖先上删除 这道题巧妙在于其可以对于 \(dfs\) 序/括号序列 \(hash ...

  8. LOJ 6060「2017 山东一轮集训 Day1 / SDWC2018 Day1」Set(线性基,贪心)

    LOJ 6060「2017 山东一轮集训 Day1 / SDWC2018 Day1」Set $ solution: $ 这一题的重点在于优先级问题,我们应该先保证总和最大,然后再保证某一个最小.于是我 ...

  9. 【LOJ6077】「2017 山东一轮集训 Day7」逆序对 生成函数+组合数+DP

    [LOJ6077]「2017 山东一轮集训 Day7」逆序对 题目描述 给定 n,k ,请求出长度为 n的逆序对数恰好为 k 的排列的个数.答案对 109+7 取模. 对于一个长度为 n 的排列 p ...

随机推荐

  1. 听雷哥浅谈Redis

    Linux下安装redis 1.下载源码,解压缩后编译源码. $ wget http://download.redis.io/releases/redis-2.8.3.tar.gz $ tar xzf ...

  2. 前端技术Jquery与Ajax使用总结

    前端技术Jquery与Ajax使用总结 虽然主要是做的后端,但是由于有些时候也要写写前台的界面,因此也就学习了下Jquery和Ajax的一些知识,虽说此次写的这些对于前端大神来说有些班门弄斧的感觉,但 ...

  3. JMeter学习笔记(九) 参数化4--User Variables

    4.User Variables 用户参数 1)线程组右键添加 -> 前置处理器 -> 用户参数 2)配置用户参数 3)添加HTTP请求,引用用户参数,格式: ${} 4)配置线程数 5) ...

  4. fiddler显示出服务器IP方法

    fiddler的配置中是看不到服务器的IP的 1.打开进入fiddler界面,按快捷键ctrl+r 或者按照图中点击,进入customrules.js文件里. 2.在customrules.js文件里 ...

  5. bug单的提交

    顶头信息 所属产品,所属项目,所属模块,影响版本,当前指派,bug类型:代码错误,界面优化,设计缺陷,性能问题,标准规范,其他,安全相关.bug标题,严重程度,优先级 缺陷描述 bug描述,预置条件, ...

  6. Linux开发C语言规范

    -Iinclude:找头文件目录 ,获取头文件的目录 -C:创建.o文件 .h:文件用来声明函数,即写一个函数名. 如 int add(); int div(); int mul(); .c:文件定义 ...

  7. 剑指offer-变态跳台阶09

    题目描述 一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级.求该青蛙跳上一个n级的台阶总共有多少种跳法. class Solution: def jumpFloorII(self, n ...

  8. MyBatis实例教程--以接口的方式编程

    以接口的方式编程: 只需要修改两个地方即可, 1.mapper.xml(实体类)配置文件, 注意mapper的namespace的名字是mapper对象的完整路径名com.xiamen.mapper. ...

  9. Pro Git - 笔记3

    Git Branching Branches in a Nutshell Branches in a Nutshell let’s assume that you have a directory c ...

  10. Linux 简单socket实现UDP通信

    服务器端 #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sy ...