CodeCraft-22 and Codeforces Round #795 (Div. 2) C. Sum of Substrings 解题报告

原题链接:Problem - 1691C - Codeforces

题目描述:

You are given a binary string ss of length nn.

Let's define didi as the number whose decimal representation is sisi+1sisi+1 (possibly, with a leading zero). We define f(s)f(s) to be the sum of all the valid didi. In other words, f(s)=∑i=1n−1dif(s)=∑i=1n−1di.

For example, for the string s=1011s=1011:

  • d1=10d1=10 (ten);
  • d2=01d2=01 (one)
  • d3=11d3=11 (eleven);
  • f(s)=10+01+11=22f(s)=10+01+11=22.

In one operation you can swap any two adjacent elements of the string. Find the minimum value of f(s)f(s) that can be achieved if at most kk operations are allowed.

Input

Each test contains multiple test cases. The first line contains the number of test cases tt (1≤t≤1051≤t≤105). Description of the test cases follows.

First line of each test case contains two integers nn and kk (2≤n≤1052≤n≤105, 0≤k≤1090≤k≤109) — the length of the string and the maximum number of operations allowed.

The second line of each test case contains the binary string ss of length nn, consisting of only zeros and ones.

It is also given that sum of nn over all the test cases doesn't exceed 105105.

Output

For each test case, print the minimum value of f(s)f(s) you can obtain with at most kk operations.

Example

input

Copy

3
4 0
1010
7 1
0010100
5 2
00110

output

Copy

21
22
12

Note

  • For the first example, you can't do any operation so the optimal string is ss itself. f(s)=f(1010)=10+01+10=21f(s)=f(1010)=10+01+10=21.
  • For the second example, one of the optimal strings you can obtain is "0011000". The string has an ff value of 2222.
  • For the third example, one of the optimal strings you can obtain is "00011". The string has an ff value of 1212.

解题思路:

答案初始应该为n,因为每个字符单独拿出来都是符合题意的。。在纸上模拟会发现,,当第i位和第i+1位字符不同, 则以第i个数字结尾向前扩展任意长度的子串都是满足题意的,所以但凡第i位和第i+1位字符不同,我们就可以给答案增加i。

比如序列是xxxxxxxxxxxx01,我们可以通过若干次操作把前面的x全部变成0,因为假如前面是0那就不用操作,如果前面是1,那我们可以用倒数第二个数0和前面的数组成10然后合成0重复这样的操作就可以使得所有的x变为0,那么就成为了00……01的这种形式,然后就可以直接合并成1

同理假如序列是xxxxxxxxxxxx10,我们可以通过若干次操作把前面的x全部变成1,因为假如前面是1那就不用操作,如果前面是0,那我们可以用倒数第二个数1和前面的数组成01然后合成1重复这样的操作就可以使得所有的x变为1,那么就成为了11……10的这种形式,然后就可以直接合并成0
 

代码(CPP):

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn = 1e3 + 10;
const int INF = 0x3fffffff;

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cout << fixed;
    cout.precision(18);

    int t;
    cin >> t;
    while(t--)
    {
        int n;
        cin >> n;
        string s;
        cin >> s;
        s = " " + s;
        ll ans = n;
        for (int i = 1; i < n; i++)
        {
            if(s[i] != s[i + 1])
            {
                ans += i;
            }
        }
        cout << ans << "\n";
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值