C1. Sheikh (Easy version)
C1. Sheikh (Easy version)
This is the easy version of the problem. The only difference is that in this version .
You are given an array of integers .
The cost of a subsegment of the array , , is the value , where , and ( stands for bitwise XOR).
You will have query. Each query is given by a pair of numbers , , where . You need to find the subsegment , , with maximum value . If there are several answers, then among them you need to find a subsegment with the minimum length, that is, the minimum value of .
Input
Each test consists of multiple test cases. The first line contains an integer — the number of test cases. The description of test cases follows.
The first line of each test case contains two integers and — the length of the array and the number of queries.
The second line of each test case contains integers — array elements.
-th of the next lines of each test case contains two integers and — the boundaries in which we need to find the segment.
It is guaranteed that the sum of over all test cases does not exceed .
It is guaranteed that and .
Output
For each test case print pairs of numbers such that the value is maximum and among such the length is minimum. If there are several correct answers, print any of them.
Example
input
6 1 1 0 1 1 2 1 5 10 1 2 3 1 0 2 4 1 3 4 1 0 12 8 3 1 4 5 1 21 32 32 32 10 1 5 7 1 0 1 0 1 0 1 0 1 7
output
1 1 1 1 1 1 2 3 2 3 2 4
Note
In the first test case, .
In the second test case, , . Note that , but we need to find a subsegment with the minimum length among the maximum values of . So, only segments and are the correct answers.
In the fourth test case, .
There are two correct answers in the fifth test case, since and their lengths are equal.
解题思路
当固定后,是一个随着增加的递增函数,即。当加入一个新的元素,此时增加了,而的增量不会超过。要知道本质是不进位加法,因此。所以假设,那么,因此,即当固定后,是一个递增函数。如果没想到这一步的话那这道题就做不出来了。
因此,我们知道当固定后,最大值就是,又因为我们要使得区间长度尽可能小,且是一个递增函数,因此我们可以二分出值为最靠左的一个右端点。
因此做法就是枚举左端点,对于固定的左端点二分出最靠左且值为的右端点。
AC代码如下,时间复杂度为:
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 typedef long long LL; 5 6 const int N = 2e5 + 10; 7 8 LL s[N], sx[N]; 9 10 void solve() { 11 int n, m; 12 scanf("%d %d", &n, &m); 13 for (int i = 1; i <= n; i++) { 14 int x; 15 scanf("%d", &x); 16 s[i] = s[i - 1] + x; // 预处理前缀和 17 sx[i] = sx[i - 1] ^ x; // 预处理前缀异或和 18 } 19 20 while (m--) { 21 int x, y; 22 scanf("%d %d", &x, &y); 23 LL maxv = -1, a, b; // maxv是最大f值,a、b是答案的左右端点 24 for (int i = x; i <= y; i++) { // 枚举左端点i 25 int l = i, r = y; // 在区间[i, y]中找到最靠左的右端点r,使得f(i,r) = f(i,y) 26 LL t = s[y] - s[i - 1] - (sx[y] ^ sx[i - 1]); // f(i,y) 27 while (l < r) { // 二分右端点 28 int mid = l + r >> 1; 29 if (s[mid] - s[i - 1] - (sx[mid] ^ sx[i - 1]) >= t) r = mid; 30 else l = mid + 1; 31 } 32 if (t > maxv) { 33 maxv = s[l] - s[i - 1] - (sx[l] ^ sx[i - 1]); 34 a = i, b = l; 35 } 36 else if (t == maxv && b - a > l - i) { 37 a = i, b = l; 38 } 39 } 40 printf("%d %d\n", a, b); 41 } 42 } 43 44 int main() { 45 int t; 46 scanf("%d", &t); 47 while (t--) { 48 solve(); 49 } 50 51 return 0; 52 }
参考资料
Codeforces Round #830 (Div. 2) Editorial:https://codeforces.com/blog/entry/108327
本文来自博客园,作者:onlyblues,转载请注明原文链接:https://www.cnblogs.com/onlyblues/p/16835098.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效