C1. Sheikh (Easy version)

C1. Sheikh (Easy version)

This is the easy version of the problem. The only difference is that in this version $q=1$.

You are given an array of integers $a_1,a_2, \ldots,a_n$.

The cost of a subsegment of the array $[l, r]$, $1 \leq l \leq r \leq n$, is the value $f(l, r) = \operatorname{sum}(l, r) - \operatorname{xor}(l, r)$, where $\operatorname{sum}(l, r) = a_l + a_{l+1} + \ldots + a_r$, and $\operatorname{xor}(l, r) = a_l \oplus a_{l+1} \oplus \ldots \oplus a_r$ ($\oplus$ stands for bitwise XOR).

You will have $q=1$ query. Each query is given by a pair of numbers $L_i$, $R_i$, where $1 \leq L_i \leq R_i \leq n$. You need to find the subsegment $[l,r]$, $L_i \leq l \leq r \leq R_i$, with maximum value $f(l,r)$. If there are several answers, then among them you need to find a subsegment with the minimum length, that is, the minimum value of $r−l+1$.

Input

Each test consists of multiple test cases. The first line contains an integer $t$ $(1 \leq t \leq {10}^{4})$ — the number of test cases. The description of test cases follows.

The first line of each test case contains two integers $n$ and $q$ $(1 \leq n \leq {10}^{5}, q=1)$ — the length of the array and the number of queries.

The second line of each test case contains $n$ integers $a_1,a_2, \ldots,a_n$ $(0 \leq a_i \leq {10}^{9})$ — array elements.

$i$-th of the next $q$ lines of each test case contains two integers $L_i$ and $R_i$ $(1 \leq L_i \leq R_i \leq n)$ — the boundaries in which we need to find the segment.

It is guaranteed that the sum of $n$ over all test cases does not exceed $2 \cdot {10}^{5}$.

It is guaranteed that $L_1=1$ and $R_1=n$.

Output

For each test case print $q$ pairs of numbers $L_i \leq l \leq r \leq R_i$ such that the value $f(l,r)$ is maximum and among such the length $r−l+1$ 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, $f(1,1)=0−0=0$.

In the second test case, $f(1,1)=5−5=0$, $f(2,2)=10−10=0$. Note that $f(1, 2) = (10 + 5) - (10 \oplus 5) = 0$, but we need to find a subsegment with the minimum length among the maximum values of $f(l,r)$. So, only segments $[1,1]$ and $[2,2]$ are the correct answers.

In the fourth test case, $f(2, 3) = (12 + 8) - (12 \oplus 8) = 16$.

There are two correct answers in the fifth test case, since $f(2,3)=f(3,4)$ and their lengths are equal.

 

解题思路

  当$l$固定后,$f(l,r)$是一个随着$r$增加的递增函数,即$f(l, r) \leq f(l, r + 1)$。当加入一个新的元素$x$,此时$\operatorname{sum}$增加了$x$,而$\operatorname{xor}$的增量不会超过$x$。要知道$\operatorname{xor}$本质是不进位加法,因此$a \oplus x \leq a + x$。所以假设$f(l, r) = s - sx$,那么$f(l, r + 1) = (s + x) - (sx \oplus x) \geq (s + x) - (sx + x) = s - sx$,因此$f(l, r + 1) - f(l, r) \geq (s - sx) - (s - sx) = 0$,即当$l$固定后,$f(l,r)$是一个递增函数。如果没想到这一步的话那这道题就做不出来了。

  因此,我们知道当$l$固定后,最大值就是$f(l, n)$,又因为我们要使得区间长度尽可能小,且$f(l,r)$是一个递增函数,因此我们可以二分出值为$f(l, n)$最靠左的一个右端点。

  因此做法就是枚举左端点$l$,对于固定的左端点二分出最靠左且值为$f(l, n)$的右端点。

  AC代码如下,时间复杂度为$O(n \log{n})$:

 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

posted @ 2022-10-28 14:31  onlyblues  阅读(59)  评论(0编辑  收藏  举报
Web Analytics