数学问题——等差数列
题目描述 Little Gyro has just found an empty integer set A in his right pocket, and an empty integer set B in his left pocket. At the
same time, Little Gyro has already thought about two integers n, m in
his mind. As Little Gyro is bored, he decides to play with these two
sets. Then, Little Gyro is ready to divide the integer series
1,2,3…m−1,m to these two empty sets. With the following rules:
- If the number is an integer multiple of n, Little Gyro will put it in set A.
- Otherwise, Little Gyro will put it in set B instead. Now given two integers n, m, after these operations, Little Gyro wants to know the
result of sum(B)-sum(A) and ask you for help, please help him to
calculate.
输入描述: There are multiple test cases. The first line of the input contains an integer T (1 ≤ T ≤ 105), indicating the number of test
cases. For each test case: Each line contains two integers n, m (1 ≤
n, m ≤ 109), indicating the length of the sequence.
输出描述:
For each test case output an integer indicating the result of
sum(B)-sum(A).
示例1
输入
3
3 5
2 10
3 16
输出
9
-5
46
思路如下:
这一道题直接爆了求解是不行的因为数据非常多,这个时候就是数学发挥作用的时候,我们可以先求出1到m的总和,然后再求1~m中为n的倍数的总和,显然这两个求和均是,等差数列求和,最后再用第一个和减第二个和就行了,这样就大大减少了运算时间,其次我最想在这题中说的是,我们在定义 m、n 变量的时候一定要用 long long 数据类型去定义(这点很重要,因为如果我们不去这样定义,那个在 m、n参与运算的时产生的临时变量 有可能会超过 int的数据范围10^9,这样这个临时变量就会出错,在赋给一个longlong的变量当然也是错的)
题解如下:
#include<iostream>
#include<string.h>
#include<algorithm>
int buct[10005];
using namespace std;
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
long long int n,m; //这里用 long long 定义很重要
scanf("%lld%lld",&n,&m);
long long sum=0;
sum = (1+m)*m/2; // 用 long long定义变量 = 左边运算产生的临时变量为long long 类型, (1+m)*/2 运算是不会超过longlong 范围的,而换回 int 就会超,
long long zhi = 0;
zhi = (n+(m/n)*n)*(m/n); //这里的 (m/n) 到括号一定要加上,这与 / 运算符,截去运算结果的小数部分有关,而我们在这里正是 我们所想应用的这个特点
sum-=zhi;
//printf("sum:%lld zhi:%lld cha%lld",sum,zhi,sum-zhi);
printf("%lld\n",sum);
}
return 0;
}