[codeforces 1301C] Ayoub's function 容斥原理+隔板法+等差数列求和

Codeforces Round #619 (Div. 2)

[codeforces 1301C] Ayoub's function 容斥原理+隔板法+等差数列求和

总目录详见https://blog.csdn.net/mrcrack/article/details/103564004

在线测评地址https://codeforces.com/contest/1301/problem/C

ProblemLangVerdictTimeMemory
C - Ayoub's function GNU C++11Accepted93 ms0 KB

codeforces比赛时,第一次提交,无法AC,不要紧。此时建议:

1重读题目,看看是否有遗漏;

2举一些极端例子,验证自己的算法;

3重读代码,看看有无手误。

第二次,提交AC的可能性大增。

第二次提交,无法AC,可以考虑继续下一题。

该题算法核心,挨在一起的0尽可能少。

模拟了样例,找到了点感觉,继续尝试如下

00000
0

11111
5+4+3+2+1=(1+5)*5/2=15

001000
111111全集(1+6)*6/2=21
00数量(1+2)*2/2=3
000数量(1+3)*3/2=6
答案21-3-6=12容斥原理

n=5,m=0,1,2,3,4,5
00000
00100
01010
01101
01110
01111
11111

0|0|0|0|0
相邻之间可放的隔板,如上
隔板数量小于等于1的数量,那么0都是一个一个孤立的。

隔板数量大于1的数量,那么要让0的分布尽量均匀。举例如下
10 2
0001000100
0的数量8,1的数量2(可将0分成(2+1)=3块)
8/(2+1)=2,8%(2+1)=2再将余数2按1个1个的分到块中
00100100    (00)
0001000100  加入多余的0
计算过程如下
1111111111全集(1+10)*10/2=55
000数量(1+3)*3/2=6
000数量(1+3)*3/2=6
00数量(1+2)*2/2=3
答案55-6-6-3=40容斥原理

AC代码如下

#include <stdio.h>
#define LL long long
int main(){
	int t,i;
	LL n,m,cnt0,ans,a,b;
	scanf("%d",&t);
	while(t--){
		scanf("%lld%lld",&n,&m);
		cnt0=n-m,ans=0;
		if(m==0)printf("0\n");
		else if(cnt0-1<=m){
			ans+=(n+1)*n/2;
			ans-=cnt0;
			printf("%lld\n",ans);
		}else{//cnt0-1>m
			ans+=(n+1)*n/2;
			a=cnt0/(m+1),b=cnt0%(m+1);
			for(i=1;i<=b;i++)ans-=(a+1+1)*(a+1)/2;
			for(i=b+1;i<=m+1;i++)ans-=(a+1)*a/2;
			printf("%lld\n",ans);
		}
	}
	return 0;
}

 

 

 

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值