官网链接
E. Replace With the Previous, Minimize
You are given a string s of lowercase Latin letters.
The following operation can be used:
select one character (from ‘a’ to ‘z’) that occurs at least once in the string. And replace all such characters in the string with the previous one in alphabetical order on the loop. For example, replace all ‘c’ with ‘b’ or replace all ‘a’ with ‘z’.
And you are given the integer k — the maximum number of operations that can be performed. Find the minimum lexicographically possible string that can be obtained by performing no more than k operations.
The string a=a1a2…an is lexicographically smaller than the string b=b1b2…bn if there exists an index k (1 ≤ k ≤ n) such that a1 = b1, a2 = b2, …, ak−1 = bk−1, but ak < bk.
Input
The first line contains a single integer t (1 ≤ t ≤ 104) —the number of test cases in the test.
This is followed by descriptions of the test cases.
The first line of each test case contains two integers n and k (1 ≤ n ≤ 2⋅105, 1 ≤ k ≤ 109) — the size of the string s and the maximum number of operations that can be performed on the string s.
The second line of each test case contains a string s of length n consisting of lowercase Latin letters.
It is guaranteed that the sum n over all test cases does not exceed 2⋅105.
Output
For each test case, output the lexicographically minimal string that can be obtained from the string s by performing no more than k operations.
Example
input
4
3 2
cba
4 5
fgde
7 5
gndcafb
4 19
ekyv
output
aaa
agaa
bnbbabb
aapp
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
#define lowbit(x) ((x)&(-x))
#define fi first
#define se second
#define endl '\n'
#define pb push_back
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 c = getchar();
while (c < '0' || c > '9') { if (c == '-') f = -1; c = getchar(); }
while (c <= '9' && c >= '0') x = (x << 1) + (x << 3) + (c ^ 48), c = getchar();
x *= f;
}
void solve()
{
int n,k;
string s;
cin >> n >> k >> s;
int mx = 0;
for(int i = 0;i < n;i++)
{
if(s[i] - 'a' > k)//遇到的第一个就要开始操作了,因为贪心就是从第一个开始搞的
{
char l = s[i] - (k - mx),r = s[i];//在该变化区间内的字符全部变成l
for(int j = 0;j < n;j++)//变成l之后,再跟随前面的字符一起变化!
{
if(s[j] >= l && s[j] <= r) s[j] = l;
}
break;
}
mx = max(mx,s[i] - 'a');//取每次需要变成a的最大操作次数
}
for(int i = 0;i < n;i++)
if(s[i] - 'a' <= mx) s[i] = 'a';//如果变成a的操作次数小于最大的mx那就变为a
cout << s << endl;
return ;
}
int main()
{
IOS;
int T;
cin >> T;
while(T--) solve();
return 0;
}
F. Vlad and Unfinished Business
Vlad and Nastya live in a city consisting of n houses and n−1 road. From each house, you can get to the other by moving only along the roads. That is, the city is a tree.
Vlad lives in a house with index x, and Nastya lives in a house with index y. Vlad decided to visit Nastya. However, he remembered that he had postponed for later k things that he has to do before coming to Nastya. To do the i-th thing, he needs to come to the ai-th house, things can be done in any order. In 1 minute, he can walk from one house to another if they are connected by a road.
Vlad does not really like walking, so he is interested what is the minimum number of minutes he has to spend on the road to do all things and then come to Nastya. Houses a1,a2,…,ak he can visit in any order. He can visit any house multiple times (if he wants).
Input
The first line of input contains an integer t (1 ≤ t ≤ 104) — the number of input test cases. There is an empty line before each test case.
The first line of each test case contains two integers n and k (1 ≤ k ≤ n ≤ 2⋅105) — the number of houses and things, respectively.
The second line of each test case contains two integers x and y (1 ≤x,y ≤ n) — indices of the houses where Vlad and Nastya live, respectively.
The third line of each test case contains k integers a1,a2,…,ak (1 ≤ ai ≤ n) — indices of houses Vlad need to come to do things.
The following n−1 lines contain description of city, each line contains two integers vj and uj (1 ≤ uj,vj ≤ n) — indices of houses connected by road j.
It is guaranteed that the sum of n for all cases does not exceed 2⋅105.
Output
Output t lines, each of which contains the answer to the corresponding test case of input. As an answer output single integer — the minimum number of minutes Vlad needs on the road to do all the things and come to Nastya.
Example
input
3
3 1
1 3
2
1 3
1 2
6 4
3 5
1 6 2 1
1 3
3 4
3 5
5 6
5 2
6 2
3 2
5 3
1 3
3 4
3 5
5 6
5 2
output
3
7
2
题解:
以x为根节点,将所有要去往的地点都加上(将y也加上)。然后计算每个节点的深度,并记录叶子结点的父节点,最后遍历每个要去的点,每次加2算是从要去的点回到其父节点需要2的消耗,再不断往父节点上走,最后记得减去y的深度,因为那里计算的时候多算了从y回到x的情况。
#include <bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
void solve()
{
int n,k;
cin >> n >> k;
int x,y;
cin >> x >> y;
vector<int> a(k);
for(int i = 0;i < k;i++) cin >> a[i];//需要从0开始,毕竟后面的auto操作需要用到[0]下标的数
a.push_back(y);
vector<vector<int>> adj (n + 1);//这个动态数组用的没问题
for(int i = 0;i < n - 1;i++)
{
int u,v;
cin >> u >> v;
adj[u].push_back(v);
adj[v].push_back(u);
}
vector<int> p(n + 1,-1),dep(n + 1);
auto dfs = [&](auto dfs,int u) -> void
{
for(auto v : adj[u])
{
if(v == p[u]) continue;
p[v] = u;
dep[v] = dep[u] + 1;//计算深度
dfs(dfs,v);
}
};
dfs(dfs,x);
int ans = 0;
vector<bool> st(n + 1);
st[x] = true;
for(auto u : a)
{
while(!st[u])
{
st[u] = true;
ans += 2;
u = p[u];
}
}
ans -= dep[y];//上面多计算了从y回到x的路径,应减去这个深度
cout << ans << endl;
return;
}
int main()
{
IOS;
int T;
cin >> T;
while(T--) solve();
return 0;
}
G. Sorting Pancakes
Nastya baked m pancakes and spread them on n dishes. The dishes are in a row and numbered from left to right. She put ai pancakes on the dish with the index i.
Seeing the dishes, Vlad decided to bring order to the stacks and move some pancakes. In one move, he can shift one pancake from any dish to the closest one, that is, select the dish i (ai > 0) and do one of the following:
if i > 1, put the pancake on a dish with the previous index, after this move ai=ai−1 and ai−1=ai−1+1;
if i < n, put the pancake on a dish with the following index, after this move ai=ai−1 and ai+1=ai+1+1.
Vlad wants to make the array anon-increasing, after moving as few pancakes as possible. Help him find the minimum number of moves needed for this.
The array a=[a1,a2,…,an] is called non-increasing if ai ≥ ai+1 for all i from 1 to n−1.
Input
The first line of the input contains two numbers n and m (1 ≤ n,m ≤ 250) — the number of dishes and the number of pancakes, respectively.
The second line contains n numbers ai (0 ≤ ai ≤ m), the sum of all ai is equal to m.
Output
Print a single number: the minimum number of moves required to make the array a non-increasing.
Examples
input
6 19
5 3 2 3 3 3
output
2
input
3 6
3 2 1
output
0
input
3 6
2 1 3
output
1
input
6 19
3 4 3 3 5 1
output
3
input
10 1
0 0 0 0 0 0 0 0 0 1
output
9
Note
In the first example, you first need to move the pancake from the dish 1, after which a=[4,4,2,3,3,3]. After that, you need to move the pancake from the dish 2 to the dish 3 and the array will become non-growing a=[4,3,3,3,3,3].
#include <bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
#define endl '\n'
int main()
{
IOS;
int n,m;
cin >> n >> m;
vector<vector<vector<int>>> f(n + 1,vector<vector<int>>(m + 1,vector<int>(m + 1,0x3f3f3f3f)));//三维
vector<int> a(n + 1),s(n + 1,0);
for(int i = 1;i <= n;i++) cin >> a[i],s[i] = s[i - 1] + a[i];
//f[i][j][k]:从前i个中选,且总和为j,最后一个数为k的集合
f[0][0][m] = 0;//想当于a[0] = m,方便使得后面的数都比它小
for(int i = 1;i <= n;i++)
for(int j = 0;j <= m;j++)
for(int k = 0;k <= j;k++)
for(int x = k;x <= m;x++)
f[i][j][k] = min(f[i][j][k],f[i - 1][j - k][x] + abs(s[i] - j));
int ans = 0x3f3f3f3f;
for(int i = 0;i <= m;i++) ans = min(ans,f[n][m][i]);
cout << ans << endl;
return 0;
}