原题
题目描述
样例
输入
3
5 7
7 9
1 9
输出
Case #1: 2
Case #2: 7
Case #3: 8
说明
f(1)=0.
f(2)=0.
f(3)=0.
f(4)=0.
f(5)=0.
f(6)=1:6=1+2+3.
f(7)=1:7=1+1+2+3.
f(8)=2:8=1+1+1+2+3,8=1+2+2+3.
f(9)=4:9=1+1+1+1+2+3,9=1+1+2+2+3,9=1+2+3+3,9=2+3+4.
思路
看数据猜算法,脑袋一拍我们会知道这肯定是一道打表的题,打一维的表。
因为
是首尾差等于
并且相邻两个差最多为
的递增序列。
若设第一段的数值为
,则第二段的数值为
,第三段的数值为
。我们再设第一段的长度为
,第二段的长度为
,第三段的长度为
。
则我们可以得出以下结论
-
然后用两次差分即可。
代码
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=1e5+5;
ll t,l,r,f,a[maxn<<2],b[maxn<<1];
int main()
{
for(int i=3;i<=1e5;i++)for(int j=i;j<=1e5;j+=i)a[j+3]++,a[j+i+1]--,a[j+i+2]--,a[j+i*2]++;
for(int i=1;i<=maxn;i++)a[i]+=a[i-1];
for(int i=3;i<=maxn;i++)b[i]=b[i-2]+a[i];
for(int i=3;i<=maxn;i++)b[i]+=b[i-1];
for(scanf("%lld",&t);t--;)scanf("%lld%lld",&l,&r),printf("Case #%lld: %lld\n",++f,b[r]-b[l-1]);
return 0;
}