南京理工大学C題
2317 ワード
まず、暴力は耐えられないに違いないと分析することができます.a、bの範囲は10の15次レベルなので、この問題は他の方法を探す必要があります.それは反発原理です.
1−bにおけるnと非互質の個数を求め,次いで1−(a−1)におけるnと非互質の個数を減算し,最終的に得られた結果が問題に必要な結果である.
では、どのようにして大きな数mとnが互いに質を持たない個数を迅速に求めることができますか.方法は、2,3,5のようなnの質因子を求めることです.
1-mにはm/2個の数とnに公因子2があり、m/3個の数とnに公因子3があり、m/5個の数とnに公因子5がある...しかし,m/2+m/3+m/5を最後にnと相互作用しない個数として簡単には使用できない.
10のように、m/2にもm/5にも計算するので、反発原理式として用いる必要があるのは、n/2+n/3+n/5-n/(2*3)-n/(2*5)-n/(3*5)+n/(2*3*5)+n/(2*3*5)である.
これで正しいことを保証します!!
1−bにおけるnと非互質の個数を求め,次いで1−(a−1)におけるnと非互質の個数を減算し,最終的に得られた結果が問題に必要な結果である.
では、どのようにして大きな数mとnが互いに質を持たない個数を迅速に求めることができますか.方法は、2,3,5のようなnの質因子を求めることです.
1-mにはm/2個の数とnに公因子2があり、m/3個の数とnに公因子3があり、m/5個の数とnに公因子5がある...しかし,m/2+m/3+m/5を最後にnと相互作用しない個数として簡単には使用できない.
10のように、m/2にもm/5にも計算するので、反発原理式として用いる必要があるのは、n/2+n/3+n/5-n/(2*3)-n/(2*5)-n/(3*5)+n/(2*3*5)+n/(2*3*5)である.
これで正しいことを保証します!!
#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
#include <algorithm>
#include <stack>
#include <queue>
#include <map>
#include <vector>
#include <cmath>
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
using namespace std;
const int maxx = 10000005;
const int maxn = 55555;
typedef long long int ll;
ll a[maxn], que[maxn], prime[maxx / 10];
bool visit[maxx];
int n;
void getPrime()
{
int i, j;
memset(prime, 0, sizeof(prime));
for (i = 0; i<maxx; i++)
visit[i] = true;
visit[0] = visit[1] = false;
for (i = 2; i<maxx; i++)
{
if (visit[i])
{
prime[++prime[0]] = i;
for (j = i; j<maxx; j += i)
visit[j] = false; // , ,
}
}
}
ll ans(ll nn) // 1-n n
{
ll t = n;
int i, j, k = 0;
for (i = 1; prime[i] * prime[i] <= t; i++)
{
if (t%prime[i] == 0)
{
a[k++] = prime[i];
}
while (t%prime[i] == 0) // ,
{
t /= prime[i];
}
}
if (t != 1)
a[k++] = t;
//a n
que[0] = -1;
t = n;
int kk = 1;
for (i = 0; i<k; i++) //que , ,
{
t = kk; // ,
for (int w = 0; w <t; w++)
{
que[kk++] = a[i] * (-1)*que[w];
}
}
ll res = 0;
for (i = 1; i<kk; i++)
{
res += nn / que[i];
}
return res;
}
int main(void)
{
//freopen("in.txt", "r", stdin);
int T;
ll a, b;
getPrime();
scanf("%d", &T);
while (T--)
{
scanf("%lld%lld%lld", &a, &b, &n);
printf("%lld
", b - ans(b) - (a - 1 - ans(a - 1))); // , ,
}
return 0;
}