ZJU 3629 - Treasure Hunt IV

28 篇文章 0 订阅
10 篇文章 0 订阅

 

题目地址: http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3629

 

仔细想下,应该能得出,是求的    0*0 ~ 1*1 、2*2 ~ 3*3 、  4*4~ 5*5  、……    、偶数*偶数 ~ 奇数*奇数  ……

 

每一段之间这些数的总和(包含 [偶数*偶数],但不包含 [奇数*奇数])

 

比如说, 10 :   0*0 ~  1*1  之间有 1个;2*2 ~ 3*3 之间有 5个;4*4以后的含有0个。。。   所以一共有6个。

 

(PS: 以上结论是小胖分析得到的~~)

 

再者,有一个规律 :  2*2 - 1*1=3 ; 3*3 - 2*2 = 5 ; 4*4 - 3*3 = 7 ; 5*5 - 4*4 = 9  ……    这是一个等差数列。。。

 

于是可以用等差数列求和公式来计算结果。。。

 

 

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<cmath>
#include<cstring>

using namespace std;


unsigned long long cal(unsigned long long x){
	unsigned long long t1,t2,tmp,mul;
	tmp=sqrt(x+1);
	if(tmp>0){
		mul=((tmp-1)/2+1);
		mul=mul*(mul*2-1);
	}
	else mul=0;
	t1=tmp*tmp,t2=(tmp+1)*(tmp+1);
	if((tmp&1)==0 && x>=t1 && x<t2)
		mul+=x-t1+1;
	return mul;
}

int main(){
	unsigned long long a,b;
	while(cin>>a>>b){
		cout<<cal(b)-(a==0?0:cal(a-1))<<endl; 
	}
	return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值