Codeforces Global Round 13
题目链接:http://codeforces.com/contest/1491
该场比赛共9道题(AC三道题、补题一道、读题尚未补一道、四道未读题)
AC三道,罚时2次。
A | 水题 |
B | 水题(对于接触到边缘的情况本题为考虑、否则会稍显麻烦) |
C | 思维题、从左到右依次遍历、对于每一个蹦床的情况、相邻右侧若干位置使用一维数组记录,时间复杂度,空间复杂度 |
D | 已补题、思维+位运算+前缀和、使用位运算计算两个数字的位前缀和操作、通过比较前缀和来判断是否可以到达 |
E | 待补题(斐波那契树)、一道树上操作题 |
A. K-th Largest Value
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output
You are given an array 𝑎a consisting of 𝑛n integers. Initially all elements of 𝑎a are either 00 or 11. You need to process 𝑞q queries of two kinds:
- 1 x : Assign to 𝑎𝑥ax the value 1−𝑎𝑥1−ax.
- 2 k : Print the 𝑘k-th largest value of the array.
As a reminder, 𝑘k-th largest value of the array 𝑏b is defined as following:
- Sort the array in the non-increasing order, return 𝑘k-th element from it.
For example, the second largest element in array [0,1,0,1][0,1,0,1] is 11, as after sorting in non-increasing order it becomes [1,1,0,0][1,1,0,0], and the second element in this array is equal to 11.
Input
The first line contains two integers 𝑛n and 𝑞q (1≤𝑛,𝑞≤1051≤n,q≤105) — the length of the given array and the number of queries.
The second line contains 𝑛n integers 𝑎1,𝑎2,𝑎3,…,𝑎𝑛a1,a2,a3,…,an (0≤𝑎𝑖≤10≤ai≤1) — elements of the initial array.
Each of the following 𝑞q lines contains two integers. The first integer is 𝑡t (1≤𝑡≤21≤t≤2) — the type of query.
- If 𝑡=1t=1 the second integer is 𝑥x (1≤𝑥≤𝑛1≤x≤n) — the position of the modified number. You have to assign to 𝑎𝑥ax the value 1−𝑎𝑥1−ax.
- If 𝑡=2t=2 the second integer is 𝑘k (1≤𝑘≤𝑛1≤k≤n) — you need to print the 𝑘k-th largest value of the array.
It's guaranteed that there will be at least one query of the second type (satisfying 𝑡=2t=2).
Output
For each query of the second type, print a single integer — the answer to the query.
Example
input
Copy
5 5
1 1 0 1 0
2 3
1 2
2 3
2 1
2 5
output
Copy
1
0
1
0
Note
Initially 𝑎=[1,1,0,1,0]a=[1,1,0,1,0].
The first operation is printing the third largest value, which is 11.
The second operation is assigning 𝑎2a2 the value 00, 𝑎a becomes [1,0,0,1,0][1,0,0,1,0].
The third operation is printing the third largest value, it is 00.
The fourth operation is printing the first largest value, it is 11.
The last operation is printing the fifth largest value, it is 00.
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn = 1e5 + 10;
int a[maxn];
int n, q;
int count_;
int main()
{
while(scanf("%d%d", &n, &q)!=EOF)
{
count_ = 0;
for(int i=1; i<=n; i++)
{
scanf("%d", &a[i]);
if(a[i] == 1)
count_ ++;
}
for(int i=1; i<=q; i++)
{
int x, k;
scanf("%d%d", &x, &k);
if(x == 2)
{
if(k <= count_)
printf("1\n");
else
printf("0\n");
}
else if(x == 1)
{
if(a[k] == 0)
{
a[k] = 1;
count_ ++;
}
else if(a[k] == 1)
{
a[k] = 0;
count_ --;
}
}
}
}
return 0;
}
B. Minimal Cost
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output
There is a graph of 𝑛n rows and 106+2106+2 columns, where rows are numbered from 11 to 𝑛n and columns from 00 to 106+1106+1:
Let's denote the node in the row 𝑖i and column 𝑗j by (𝑖,𝑗)(i,j).
Initially for each 𝑖i the 𝑖i-th row has exactly one obstacle — at node (𝑖,𝑎𝑖)(i,ai). You want to move some obstacles so that you can reach node (𝑛,106+1)(n,106+1) from node (1,0)(1,0) by moving through edges of this graph (you can't pass through obstacles). Moving one obstacle to an adjacent by edge free node costs 𝑢u or 𝑣v coins, as below:
- If there is an obstacle in the node (𝑖,𝑗)(i,j), you can use 𝑢u coins to move it to (𝑖−1,𝑗)(i−1,j) or (𝑖+1,𝑗)(i+1,j), if such node exists and if there is no obstacle in that node currently.
- If there is an obstacle in the node (𝑖,𝑗)(i,j), you can use 𝑣v coins to move it to (𝑖,𝑗−1)(i,j−1) or (𝑖,𝑗+1)(i,j+1), if such node exists and if there is no obstacle in that node currently.
- Note that you can't move obstacles outside the grid. For example, you can't move an obstacle from (1,1)(1,1) to (0,1)(0,1).
Refer to the picture above for a better understanding.
Now you need to calculate the minimal number of coins you need to spend to be able to reach node (𝑛,106+1)(n,106+1) from node (1,0)(1,0) by moving through edges of this graph without passing through obstacles.
Input
The first line contains a single integer 𝑡t (1≤𝑡≤1041≤t≤104) — the number of test cases.
The first line of each test case contains three integers 𝑛n, 𝑢u and 𝑣v (2≤𝑛≤1002≤n≤100, 1≤𝑢,𝑣≤1091≤u,v≤109) — the number of rows in the graph and the numbers of coins needed to move vertically and horizontally respectively.
The second line of each test case contains 𝑛n integers 𝑎1,𝑎2,…,𝑎𝑛a1,a2,…,an (1≤𝑎𝑖≤1061≤ai≤106) — where 𝑎𝑖ai represents that the obstacle in the 𝑖i-th row is in node (𝑖,𝑎𝑖)(i,ai).
It's guaranteed that the sum of 𝑛n over all test cases doesn't exceed 2⋅1042⋅104.
Output
For each test case, output a single integer — the minimal number of coins you need to spend to be able to reach node (𝑛,106+1)(n,106+1) from node (1,0)(1,0) by moving through edges of this graph without passing through obstacles.
It can be shown that under the constraints of the problem there is always a way to make such a trip possible.
Example
input
Copy
3
2 3 4
2 2
2 3 4
3 2
2 4 3
3 2
output
Copy
7
3
3
Note
In the first sample, two obstacles are at (1,2)(1,2) and (2,2)(2,2). You can move the obstacle on (2,2)(2,2) to (2,3)(2,3), then to (1,3)(1,3). The total cost is 𝑢+𝑣=7u+v=7 coins.
In the second sample, two obstacles are at (1,3)(1,3) and (2,2)(2,2). You can move the obstacle on (1,3)(1,3) to (2,3)(2,3). The cost is 𝑢=3u=3 coins.
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define inf 0x3f3f3f3f
const int maxn = 2e4 + 10;
int a[maxn];
int n, u, v;
int t;
int main()
{
int t;
scanf("%d", &t);
while(t--)
{
int max_ = 2;
int count_ = 0;
scanf("%d%d%d", &n, &u, &v);
for(int i = 0; i < n; i++)
{
scanf("%d", &a[i]);
}
for(int i = 1; i< n; i++)
{
if(a[i] == a[i-1])
max_ = min(max_, 2);
else if(abs(a[i] - a[i-1]) == 1)
max_ = min(max_, 1);
else if(abs(a[i] - a[i-1]) > 1)
max_ = min(max_, 0);
}
if(max_ == 0)
{
for(int i=1; i<n; i++)
{
if(abs(a[i] - a[i-1]) > 1)
break;
if(a[i] == 0)
{
count_++;
break;
}
}
for(int i= n-2; i>=0; i--)
{
if(abs(a[i] - a[i+1]) > 1)
break;
if(a[i] == 1e6 + 1)
{
count_++;
break;
}
}
cout << count_ * min(u, v) << endl;
}
else if(max_ == 1)
{
max_ = min(u, v);
cout << max_ << endl;
}
else if(max_ == 2)
{
max_ = min(u + v, v * 2);
cout << max_ << endl;
}
}
return 0;
}
C. Pekora and Trampoline
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output
There is a trampoline park with 𝑛n trampolines in a line. The 𝑖i-th of which has strength 𝑆𝑖Si.
Pekora can jump on trampolines in multiple passes. She starts the pass by jumping on any trampoline of her choice.
If at the moment Pekora jumps on trampoline 𝑖i, the trampoline will launch her to position 𝑖+𝑆𝑖i+Si, and 𝑆𝑖Si will become equal to max(𝑆𝑖−1,1)max(Si−1,1). In other words, 𝑆𝑖Si will decrease by 11, except of the case 𝑆𝑖=1Si=1, when 𝑆𝑖Si will remain equal to 11.
If there is no trampoline in position 𝑖+𝑆𝑖i+Si, then this pass is over. Otherwise, Pekora will continue the pass by jumping from the trampoline at position 𝑖+𝑆𝑖i+Si by the same rule as above.
Pekora can't stop jumping during the pass until she lands at the position larger than 𝑛n (in which there is no trampoline). Poor Pekora!
Pekora is a naughty rabbit and wants to ruin the trampoline park by reducing all 𝑆𝑖Si to 11. What is the minimum number of passes she needs to reduce all 𝑆𝑖Si to 11?
Input
The first line contains a single integer 𝑡t (1≤𝑡≤5001≤t≤500) — the number of test cases.
The first line of each test case contains a single integer 𝑛n (1≤𝑛≤50001≤n≤5000) — the number of trampolines.
The second line of each test case contains 𝑛n integers 𝑆1,𝑆2,…,𝑆𝑛S1,S2,…,Sn (1≤𝑆𝑖≤1091≤Si≤109), where 𝑆𝑖Si is the strength of the 𝑖i-th trampoline.
It's guaranteed that the sum of 𝑛n over all test cases doesn't exceed 50005000.
Output
For each test case, output a single integer — the minimum number of passes Pekora needs to do to reduce all 𝑆𝑖Si to 11.
Example
input
Copy
3
7
1 4 2 2 2 2 2
2
2 3
5
1 1 1 1 1
output
Copy
4
3
0
Note
For the first test case, here is an optimal series of passes Pekora can take. (The bolded numbers are the positions that Pekora jumps into during these passes.)
- [1,4,2,2,2,2,2][1,4,2,2,2,2,2]
- [1,4,1,2,1,2,1][1,4,1,2,1,2,1]
- [1,3,1,2,1,1,1][1,3,1,2,1,1,1]
- [1,2,1,2,1,1,1][1,2,1,2,1,1,1]
For the second test case, the optimal series of passes is show below.
- [2,3][2,3]
- [1,3][1,3]
- [1,2][1,2]
For the third test case, all 𝑆𝑖Si are already equal to 11.
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const ll maxn = 5005;
ll t, n;
ll s[maxn];
ll val[maxn];
ll count_;
int main()
{
scanf("%lld", &t);
while(t--)
{
count_ = 0;
scanf("%lld", &n);
for(ll i=1; i<=n; i++)
{
scanf("%lld", &s[i]);
}
memset(val, 0, sizeof(val));
for(ll i=1; i<=n; i++)
{
ll k = (s[i] - 1) - val[i];
if(k > 0)
{
count_ += k;
}
for(ll j = 2; j <= s[i]; j++)
{
if(i + j <= n)
val[i + j] ++;
else
break;
}
if(k < 0)
{
k = abs(k);
if(i + 1 <= n)
val[i+1] += k;
}
}
printf("%lld\n", count_);
}
return 0;
}
D. Zookeeper and The Infinite Zoo
time limit per test
3 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output
There is a new attraction in Singapore Zoo: The Infinite Zoo.
The Infinite Zoo can be represented by a graph with an infinite number of vertices labeled 1,2,3,…1,2,3,…. There is a directed edge from vertex 𝑢u to vertex 𝑢+𝑣u+v if and only if 𝑢&𝑣=𝑣u&v=v, where && denotes the bitwise AND operation. There are no other edges in the graph.
Zookeeper has 𝑞q queries. In the 𝑖i-th query she will ask you if she can travel from vertex 𝑢𝑖ui to vertex 𝑣𝑖vi by going through directed edges.
Input
The first line contains an integer 𝑞q (1≤𝑞≤1051≤q≤105) — the number of queries.
The 𝑖i-th of the next 𝑞q lines will contain two integers 𝑢𝑖ui, 𝑣𝑖vi (1≤𝑢𝑖,𝑣𝑖<2301≤ui,vi<230) — a query made by Zookeeper.
Output
For the 𝑖i-th of the 𝑞q queries, output "YES" in a single line if Zookeeper can travel from vertex 𝑢𝑖ui to vertex 𝑣𝑖vi. Otherwise, output "NO".
You can print your answer in any case. For example, if the answer is "YES", then the output "Yes" or "yeS" will also be considered as correct answer.
Example
input
Copy
5
1 4
3 6
1 6
6 2
5 5
output
Copy
YES
YES
NO
NO
YES
Note
The subgraph on vertices 1,2,3,4,5,61,2,3,4,5,6 is shown below.
#include<bits/stdc++.h>
using namespace std;
const int maxn = 32;
int ansu[maxn];
int ansv[maxn];
bool check(int u, int v)
{
int len;
int count_ = 0;
ansu[count_] = u & 1;
u = u >> 1;
ansv[count_] = v & 1;
v = v >> 1;
count_ ++;
while(v)
{
ansu[count_] = ansu[count_ - 1] + (u & 1);
u = u >> 1;
ansv[count_] = ansv[count_ - 1] + (v & 1);
v = v >> 1;
count_++;
}
len = count_;
bool flag = true;
for(int i=0; i<len; i++)
{
//cout << ansu[i] << " " << ansv[i] << endl;
if(ansu[i] < ansv[i])
{
flag = false;
break;
}
}
return flag;
}
int main()
{
int q, u, v;
scanf("%d", &q);
while(q--)
{
memset(ansu, 0, sizeof(ansu));
memset(ansv, 0, sizeof(ansv));
scanf("%d%d", &u, &v);
if(u == v)
{
cout << "YES" << endl;
}
else if(u > v)
{
cout << "NO" << endl;
}
else if(u < v)
{
if(check(u, v))
{
cout << "YES" << endl;
}
else
{
cout << "NO" << endl;
}
}
}
return 0;
}