C. Ayoub‘s function(推公式)

Ayoub thinks that he is a very smart person, so he created a function f(s)f(s), where ss is a binary string (a string which contains only symbols "0" and "1"). The function f(s)f(s) is equal to the number of substrings in the string ss that contains at least one symbol, that is equal to "1".

More formally, f(s)f(s) is equal to the number of pairs of integers (l,r)(l,r), such that 1≤l≤r≤|s|1≤l≤r≤|s| (where |s||s| is equal to the length of string ss), such that at least one of the symbols sl,sl+1,…,srsl,sl+1,…,sr is equal to "1".

For example, if s=s="01010" then f(s)=12f(s)=12, because there are 1212 such pairs (l,r)(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)(1,2),(1,3),(1,4),(1,5),(2,2),(2,3),(2,4),(2,5),(3,4),(3,5),(4,4),(4,5).

Ayoub also thinks that he is smarter than Mahmoud so he gave him two integers nn and mm and asked him this problem. For all binary strings ss of length nn which contains exactly mm symbols equal to "1", find the maximum value of f(s)f(s).

Mahmoud couldn't solve the problem so he asked you for help. Can you help him?

题意:有一个01串,长度为n,1的个数是m

求至少包含一个1的连续的子串的最大数量

思路:可以发现当m个1把0平均分成m+1段的时候子串数量是最大的

先算出最多的情况的数量,即全是1的情况的子串的数量:sum=(op+1)*op/2

然后我们再减去0不能构成的子串的数量:

当连续的0的个数是op时:他组成的全是0的子串的数量是(op+1)*op/2

然后再乘他们的个数

0的个数有n-m个,m个1把0分成m+1段,每段就是op=(n-m)/(m+1)

还有不能平均分的情况,那么就有(n-m)%(m+1)个长度是op+1的0

然后我们分别算出来这两种情况的子串的数量,用最大情况减去就可以啦

/*

 .----------------.  .----------------.  .----------------.  .----------------. 
| .--------------. || .--------------. || .--------------. || .--------------. |
| |  ________    | || |  _________   | || | ____    ____ | || |     ____     | |
| | |_   ___ `.  | || | |_   ___  |  | || ||_   \  /   _|| || |   .'    `.   | |
| |   | |   `. \ | || |   | |_  \_|  | || |  |   \/   |  | || |  /  .--.  \  | |
| |   | |    | | | || |   |  _|  _   | || |  | |\  /| |  | || |  | |    | |  | |
| |  _| |___.' / | || |  _| |___/ |  | || | _| |_\/_| |_ | || |  \  `--'  /  | |
| | |________.'  | || | |_________|  | || ||_____||_____|| || |   `.____.'   | |
| |              | || |              | || |              | || |              | |
| '--------------' || '--------------' || '--------------' || '--------------' |
 '----------------'  '----------------'  '----------------'  '----------------'

*/
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#include<set>
#include<map>
#include<queue>
#include<deque>
#include<cmath>
#include<stack>
#define int long long
#define lowbit(x) x&(-x)
#define PI 3.1415926535
#define endl "\n"
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
int gcd(int a,int b){
	return b>0 ? gcd(b,a%b):a;
}
/*
int dx[8]={-2,-2,-1,1,2,2,-1,1};
int dy[8]={-1,1,2,2,1,-1,-2,-2};
int dx[4]={0,-1,0,1};
int dy[4]={-1,0,1,0};
int dx[8]={-1,1,0,0,-1,-1,1,1};
int dy[8]={0,0,-1,1,-1,1,-1,1};
*/
//int e[N],ne[N],h[N],idx,w[N];
/*void add(int a,int b,int c){
	e[idx]=b;
	w[idx]=c;
	ne[idx]=h[a];
	h[a]=idx++;
}
*/
const int N=1000+10,p=1e9+7;
int n,k,m;
int a[N];
void sove(){
	cin>>n>>m;
	int sum=(n+1)*n/2;//全是1
	int op=(n-m)/(m+1);
	int k=(n-m)%(m+1);
	int tmp=m+1-k;
	int con1=tmp*(op+1)*op/2;
	int con2=k*(op+2)*(op+1)/2;
	cout<<sum-(con1+con2)<<endl;
}

signed main(){
	ios::sync_with_stdio(false);
	cin.tie() ,cout.tie() ;
	int t=1;
	cin>>t;
	while(t--){
		sove();
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值