K - 简单求和

小Kevin从没有听说过单词“无限”。于是他请导师给他解释这个词。他的导师知道“无限”是一个非常大的数。为了展示无限可能有多大, 他的导师给了他一个挑战: 求从1到 N的数的和。和数开始变得非常大,并且已经超出了“long long int”的表示范围。于是,这一课非常清晰。

现在,他的导师引入了取余的概念并让他只保留余数而非巨大的数。 然后, 导师给了他一个计算的公式:

输入
第一行包含 T, 测试数据的组数。 后跟 T行,每行包含2个空白分隔的整数N _m_
数据范围
1 ≤ T ≤ 1000 
1 ≤ N ≤ 10^9
1 ≤ m ≤ 10^9
输出
对每组测试数据,输出一行包含一个结果。
Input
3
10 5
10 3
5 5
Output
20
10
10

测试数据1: N = 10 m = 5, 

1%5 + 2%5 + 3%5 + 4%5 + 5%5 + 6%5 + 7%5 + 8%5 + 9%5 + 10%5 = 20. 

测试数据2和3可以类似解释。



分析:把n与m的关系式如上解释列出后,可找到规律:当n=m时,m前的关系式和为前m-1项的和,所以可得a=n/m;a为一共有多少组这样的数据,所以sum=m*(m-1)/2*a;(用到中学时的等差数列前N项和

Sn=na1+[n(n-1)/2]d); b=n%m为余下的个数,再对b进行前b项求和;

注:a1=1,d=1;



代码:

#include<stdio.h>
int main()
{
int t;
long long a,b,sum,sum1,m,n;
scanf("%d",&t);
while(t--)
{
scanf("%lld%lld",&n,&m);
a=n/m;
b=n%m;
sum=m*(m-1)/2*a;
sum1=b*(b+1)/2;
printf("%lld\n",sum+sum1);
}
return 0;
 } 


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值