题意:
定义函数F(x) :
区间[1,x]上的y是满足:GCD(x,y)>1 && x%y>0的 y的个数。
问:对于任意区间[l,r] 上的F(l···r) 有几个函数值是奇数的。
打表找规律。
打的是[1,x]区间的结果
把所有结果不相同的值打出来(因为结果是递增的,所以只观察不相同的结果)
发现:ans = x/2-2 || x/2-1
再把所有结果不同 && x/2-1的值打出来
发现 sqrt(x) &1 == 1
得到:ans = x/2-2 + (sqrt(x)&1);
且x<6时 ans = 0
不知为何交c++就错。
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<math.h>
using namespace std;
#define ll __int64
/*
int Gcd(int x,int y){
if(x>y)swap(x,y);
while(x){
y %= x;
swap(x,y);
}
return y;
}
int f(int x){
int ans = 0;
for(int i = 2; i < x; i++)
ans += (Gcd(i,x)!=1)&&(x%i);
return ans;
}
int main(){
int n, last = -1;
for(int j = 1; j <= 10000; j++){
n = j;
int ans = 0;
for(int i = 1; i <= n; i++)ans += f(i)&1;
if(ans!=last && j/2!=ans+2){
last = ans,printf("%5d:%d\n",j,ans);
}
}
return 0;
}/*
*/
int sqrt(__int64 l,__int64 r,__int64 a)
{
__int64 mid=(l+r)/2;
if(l>r)
return r;
if(a/mid>mid)
return sqrt(mid+1,r,a);
else if(a/mid<mid)
return sqrt(l,mid-1,a);
else
return mid;
}
ll go(ll x){
if(x<5)return 0;
ll ans = x/2-2;
ll dou = sqrt(1,x,x);
dou = dou&1;
return ans+dou;
}
int main(){
ll l,r; int T;scanf("%d",&T);
while(T--){
scanf("%I64d %I64d",&l,&r);
printf("%I64d\n", go(r)-go(l-1));
}
return 0;
}