题意
给定A,B。求值
∑
i
=
A
B
∑
i
j
=
1
⌊
i
j
⌋
×
(
−
1
)
j
\sum_{i=A}^{B}\sum_{i}^{j=1}\left \lfloor \frac{i}{j} \right \rfloor \times (-1)^ {j}
i=A∑Bi∑j=1⌊ji⌋×(−1)j
数据规模与约定
对于
50
%
50\%
50% 的数据:
1
≤
A
≤
B
≤
5
×
1
0
3
1\le A\le B\le 5\times 10^{3}
1≤A≤B≤5×103
对于
70
%
70\%
70% 的数据:
1
≤
A
≤
B
≤
5
×
1
0
4
1\le A\le B\le 5\times 10^{4}
1≤A≤B≤5×104
对于
100
%
100\%
100% 的数据:
1
≤
A
≤
B
≤
2
×
1
0
7
1\le A\le B\le 2\times 10^{7}
1≤A≤B≤2×107
50分思路
1.解析题意,可以得到一串暴力代码
code↓
#include <bits/stdc++.h>
using namespace std;
long long a,b;
long long f(long long x,long long y){
long long sum=0;
for(int i=a;i<=b;i++){
for(int j=1;j<=i;j++){
// cout<<i<<" "<<j<<" "<<i/j<<" "<<sum<<" ";
if(j%2==0) sum+=(i/j);
else sum+=-(i/j);
// cout<<sum<<endl;
}
}
return sum;
}
int main(){
// freopen("sum.in","r",stdin);
// freopen("sum.out","w",stdout);
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
cin>>a>>b;
cout<<f(a,b);
return 0;
}
70分思路
1.通过暴力打表找规律题意中的向下取整
可得 i / j 向下取整
中必定是有重复的,而 (-1)^j
则说明了当
j
j
j为奇数
时这个数便是负数
,而当
j
j
j 为偶数
时这个数便是正数
。
我们来看一串数字:
i j i/j sum 正负性
99 19 5 -67 -72 -
99 20 4 -72 -68 +
99 21 4 -68 -72 -
99 22 4 -72 -68 +
99 23 4 -68 -72 -
99 24 4 -72 -68 +
99 25 3 -68 -71 -
//sum有两个,因为前一个是sum进行变化前的,后一个是sum进行变化后的
从上述的数字中我们可以发现,其中的i/j
是重复的,但是怎么计算他们这串数字的值呢?
这串数字具有正负性,我们可以总结出一个规律
1 2 3 4 5 6 7 8 vis
-1 +1 -1 +1 -1 +1 -1 +1 val
start num end
1 0 0
1 1 -1
0 0 0
0 1 1
//其中的0代表偶数,1代表奇数。
//start代表开始的数的奇偶性,num代表总共的个数的奇偶性,end代表结果的奇偶性
这串规律就是当个数
为偶数
时结果一定为偶数个
数相加,因为它的值是相同的,所以偶数个
数相加的结果为0
当个数
为奇数
时:
如果开始的那个数为奇数
,那结果就应该减去现在的值,也就是-(i/j)
,
如果开始的那个数为偶数
,那结果就应该加上现在的值,也就是+(i/j)
。
code↓
#include <bits/stdc++.h>
using namespace std;
long long a,b;
long long f(long long x,long long y){
long long sum=0;
for(int i=a;i<=b;i++){
long long val=i,vis=1;//val表示现在的值,vis表示现在的编号,也就是上述的start
while(1){
long long sum1=0,bj=i/val,num=bj-vis+1; //sum1是当前区间的和
if(num%2!=0){//,bj是结束的数的编号,num是整个区间的个数
if(vis%2==0) sum1+=val;
else sum1-=val;
}
vis=vis+num;
val=i/vis;
sum+=sum1;
if(vis==i+1) break;//因为是直接加的num,所以会是i+1
}
}
return sum;
}
int main(){
// freopen("sum.in","r",stdin);
// freopen("sum.out","w",stdout);
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
cin>>a>>b;
cout<<f(a,b);
return 0;
}