Codeforces Round #768 (Div. 2)
B. Fun with Even Subarrays
You are given an array \(a\) of \(n\) elements. You can apply the following operation to it any number of times:
Select some subarray from a of even size \(2k\) that begins at position \(l\) \((1≤l≤l+2⋅k−1≤n, k≥1)\) and for each \(i\) between \(0\) and \(k−1\) (inclusive), assign the value \(a_l+k+i\) to \(a_l+i\).
For example, if \(a=[2,1,3,4,5,3]\), then choose \(l=1\) and \(k=2\), applying this operation the array will become \(a=[3,4,3,4,5,3]\).
Find the minimum number of operations (possibly zero) needed to make all the elements of the array equal.
Input
The input consists of multiple test cases. The first line contains a single integer \(t (1≤t≤2⋅10^4\)) — the number of test cases. Description of the test cases follows.
The first line of each test case contains an integer \(n (1≤n≤2⋅10^5)\) — the length of the array.
The second line of each test case consists of \(n\) integers \(a_1,a_2,…,a_n (1≤a_i≤n)\) — the elements of the array \(a\).
It is guaranteed that the sum of n over all test cases does not exceed \(2⋅10^5\).
Output
Print \(t\) lines, each line containing the answer to the corresponding test case — the minimum number of operations needed to make equal all the elements of the array with the given operation.
Example
input
5
3
1 1 1
2
2 1
5
4 4 4 2 4
4
4 2 1 3
1
1
output
0
1
1
2
0
Note
In the first test, all elements are equal, therefore no operations are needed.
In the second test, you can apply one operation with \(k=1\) and \(l=1\), set \(a_1:=a_2\), and the array becomes \([1,1]\) with \(1\) operation.
In the third test, you can apply one operation with \(k=1\) and \(l=4\), set \(a_4:=a_5\), and the array becomes \([4,4,4,4,4]\).
In the fourth test, you can apply one operation with \(k=1\) and \(l=3\), set \(a_3:=a_4\), and the array becomes \([4,2,3,3]\), then you can apply another operation with \(k=2\) and \(l=1\), set \(a_1:=a_3, a_2:=a_4\), and the array becomes \([3,3,3,3]\).
In the fifth test, there is only one element, therefore no operations are needed.
解题思路
思维
每次都是从后面的数字往前面复制相同长度的一段,可知最后数组中相等的元素一定是最后一个数字,可先找出最后数字相等的那段,然后像滚雪球一样往前滚,注意其中有些可能是等于最后一个数字的,这些可以跳过
- 时间复杂度:\(O(n)\)
代码
// Problem: B. Fun with Even Subarrays
// Contest: Codeforces - Codeforces Round #768 (Div. 2)
// URL: https://codeforces.ml/contest/1631/problem/B
// Memory Limit: 256 MB
// Time Limit: 1000 ms
// %%%Skyqwq
#include <bits/stdc++.h>
#define pb push_back
#define fi first
#define se second
#define mp make_pair
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
template <typename T> bool chkMax(T &x, T y) { return (y > x) ? x = y, 1 : 0; }
template <typename T> bool chkMin(T &x, T y) { return (y < x) ? x = y, 1 : 0; }
template <typename T> void inline read(T &x) {
int f = 1; x = 0; char s = getchar();
while (s < '0' || s > '9') { if (s == '-') f = -1; s = getchar(); }
while (s <= '9' && s >= '0') x = x * 10 + (s ^ 48), s = getchar();
x *= f;
}
int t,n,a[200005];
int main()
{
for(scanf("%d",&t);t;t--)
{
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
int res=0;
int x=1;
int pos=n-1;
while(pos>=1)
{
if(pos>=1&&a[pos]!=a[n])
{
res++;
pos=2*pos-n;
}
else if(pos>=1&&a[pos]==a[n])pos--;
}
printf("%d\n",res);
}
return 0;
}
C. And Matching
You are given a set of \(n\) (\(n\) is always a power of \(2\)) elements containing all integers \(0,1,2,…,n−1\) exactly once.
Find \(n/2\) pairs of elements such that:
Each element in the set is in exactly one pair.
The sum over all pairs of the bitwise AND of its elements must be exactly equal to \(k\). Formally, if \(a_i\) and \(b_i\) are the elements of the \(i-th\) pair, then the following must hold:
\(∑_{i=1}^{n/2}a_i\& b_i=k\),
where \(\&\) denotes the bitwise AND operation.
If there are many solutions, print any of them, if there is no solution, print \(−1\) instead.
Input
The input consists of multiple test cases. The first line contains a single integer \(t (1≤t≤400)\) — the number of test cases. Description of the test cases follows.
Each test case consists of a single line with two integers \(n\) and \(k\) (\(4≤n≤2^{16}, n\) is a power of \(2\), \(0≤k≤n−1\)).
The sum of \(n\) over all test cases does not exceed $2^{16}. All test cases in each individual input will be pairwise different.
Output
For each test case, if there is no solution, print a single line with the integer \(−1\).
Otherwise, print \(n/2\) lines, the $i-th4 of them must contain \(a_i\) and \(b_i\), the elements in the \(i-th\) pair.
If there are many solutions, print any of them. Print the pairs and the elements in the pairs in any order.
Example
input
4
4 0
4 1
4 2
4 3
output
0 3
1 2
0 2
1 3
0 1
2 3
-1
Note
In the first test, \((0\&3)+(1\&2)=0.\)
In the second test, \((0\&2)+(1\&3)=1.\)
In the third test, \((0\&1)+(2\&3)=2.\)
In the fourth test, there is no solution.
解题思路
构造
首先需要注意 \(k\) 的取值范围,任意两个数的\(\&\)运算之和不止 \(n-1\),对于 \(k\) 不妨考虑分类讨论:
-
\(k=0\) 时,让首尾两个数依次组成一对
-
\(k>0\, and\, k<n-1\) 时,在上面的基础上,让 \(n-1\) 跟 \(k\) 组成一对,\(0\) 跟 \(n-1-k\) 组成一对
-
\(k=n-1\) 时,
-
- \(n=4\) 时无解
-
- 否则,让 \(n-1\) 跟 \(n-2\),\(1\) 跟 \(n-3\),\(0\) 跟 \(3\)组成一对
-
时间复杂度:\(O(n)\)
代码
// Problem: C. And Matching
// Contest: Codeforces - Codeforces Round #768 (Div. 2)
// URL: https://codeforces.com/contest/1631/problem/C
// Memory Limit: 256 MB
// Time Limit: 1000 ms
// %%%Skyqwq
#include <bits/stdc++.h>
#define pb push_back
#define fi first
#define se second
#define mp make_pair
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
template <typename T> bool chkMax(T &x, T y) { return (y > x) ? x = y, 1 : 0; }
template <typename T> bool chkMin(T &x, T y) { return (y < x) ? x = y, 1 : 0; }
template <typename T> void inline read(T &x) {
int f = 1; x = 0; char s = getchar();
while (s < '0' || s > '9') { if (s == '-') f = -1; s = getchar(); }
while (s <= '9' && s >= '0') x = x * 10 + (s ^ 48), s = getchar();
x *= f;
}
int t,n,k;
int main()
{
for(scanf("%d",&t);t;t--)
{
scanf("%d%d",&n,&k);
if(k==0)
for(int i=0;i<n/2;i++)printf("%d %d\n",i,n-1-i);
else if(k>0&&k<n-1)
{
printf("%d %d\n",k,n-1);
printf("0 %d\n",n-1-k);
for(int i=1;i<n/2;i++)
if(i!=k&&i!=n-1-k)printf("%d %d\n",i,n-1-i);
}
else if(k==n-1)
{
if(n<=4)puts("-1");
else
{
puts("0 2");
printf("%d %d\n",1,n-3);
printf("%d %d\n",n-2,n-1);
for(int i=3;i<n/2;i++)printf("%d %d\n",i,n-1-i);
}
}
else
puts("-1");
}
return 0;
}