C. Ayoub‘s function(逆向思维)

Problem - 1301C - Codeforces

阿尤布认为自己是一个非常聪明的人,所以他创建了一个函数f(s),其中s是一个二进制字符串(一个只包含符号 "0 "和 "1 "的字符串)。函数f(s)等于字符串s中至少包含一个符号的子串的数量,即等于 "1"。

更正式地说,f(s)等于有多少对整数(l,r),使得1≤l≤r≤|s|(其中|s|等于字符串s的长度),使得符号sl,sl+1,...,sr中至少有一个等于 "1"。

例如,如果s="01010",那么f(s)=12,因为有12个这样的对(l,r)。(1,2),(1,3),(1,4),(1,5),(2,2),(2,3),(2,4),(2,5),(3,4),(3,5),(4,4),(4,5).

阿尤布也认为他比马哈茂德聪明,所以他给了他两个整数n和m,并问他这个问题。对于所有长度为n的二进制字符串s,其中正好包含m个等于 "1 "的符号,找出f(s)的最大值。

马哈茂德无法解决这个问题,所以他向你寻求帮助。你能帮助他吗?

输入
输入由多个测试案例组成。第一行包含一个整数t(1≤t≤105)--测试案例的数量。接下来是测试用例的描述。

每个测试用例的唯一一行包含两个整数n,m(1≤n≤109,0≤m≤n)--字符串的长度和其中等于 "1 "的符号数。

输出
对每个测试案例打印一个整数--f(s)在所有长度为n的字符串中的最大值,其中正好有m个符号,等于 "1"。

例子
inputCopy
5
3 1
3 2
3 3
4 0
5 2
输出拷贝
4
5
6
0
12
注意
在第一个测试案例中,只存在3个长度为3的字符串,它们正好有一个符号,等于 "1"。这些字符串是:s1="100",s2="010",s3="001"。它们的f值是:f(s1)=3,f(s2)=4,f(s3)=3,所以最大值是4,答案是4。

在第二个测试案例中,最大值的字符串s是 "101"。

在第三个测试案例中,最大值的字符串s是 "111"。

在第四个测试案例中,唯一一个长度为4的字符串s,正好有0个符号,等于 "1 "的是 "0000",该字符串的f值是0,所以答案是0。

在第五个测试案例中,具有最大值的字符串s是 "01010",它在问题陈述中被描述为一个例子。

题意:你有一个长度为n,m个1的01字符串,构造一个串,求最大包含1的子串数

题解:反过来想假设所有子串都符合要求 - 只含0的子串数即为所求,要想只含0的子串数最小应让他们分隔开

0的个数为n = n - m ,

1的个数为m,所以可以分隔出m+1段只含0串

每段只含0串的长度为a = n/m

有n%m段只含0串为a+1

接下来计算就可以了

#include<bits\stdc++.h>
using namespace std;
int main()
{
	int t;
	scanf("%d",&t);
	while(t--)
	{
		long long n,m;
		cin >> n >> m;
		long long ans = n*(n+1)/2;
		n = n - m;
		m++;
		long long a = n/m;
		long long b = n%m;
		ans = ans - a*(a+1)*(m - b)/2 -b*(a+1+1)*(a+1)/2;
		cout << ans <<endl; 
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值