2015多校第8场 HDU 5382 GCD?LCM! 数论公式推导
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5382
题意:函数lcm(a,b):求两整数a,b的最小公倍数;函数gcd(a,b):求两整数a,b的最大公约数。函数[exp],其中exp是一个逻辑表达式。如果逻辑表达式exp是真,那么函数[exp]的值是1,否则函数[exp]的值是0。例如:[1+2>=3] = 1 ,[1+2>=4] = 0。
求S(n)的值。
#include <bits/stdc++.h> using namespace std; typedef long long LL; const int maxn = 1e6+10; const int mod = 258280327; bool isprime[maxn]; LL prime[maxn], primecnt, num[maxn]; LL G[maxn], T[maxn], F[maxn], S[maxn]; LL qsm(LL a, LL n){ LL ret = 1; while(n){ if(n&1) ret = ret*a%mod; a=a*a%mod; n>>=1; } return ret; } void pre_deal(){ memset(isprime, true, sizeof(isprime)); memset(num, 0, sizeof(num)); for(int i=2; i<maxn; i++){ if(isprime[i]){ num[i]++; for(int j=i+i; j<maxn; j+=i){ isprime[j] = false; num[j]++; } } } for(int i=2; i<maxn; i++){ if(isprime[i]){ prime[primecnt++]=i; } } } void INIT() { pre_deal(); G[0] = 0; for(int i=1; i<maxn; i++){ G[i] = qsm(2, num[i]); } memset(T, 0, sizeof(T)); memset(F, 0, sizeof(F)); memset(S, 0, sizeof(S)); for(int i=1; i<maxn; i++){ for(int j=i; j<maxn; j+=i){ T[j]=(T[j]+G[j/i-1])%mod; } } F[1] = S[1] = 1; for(int i=2; i<maxn; i++){ F[i] = ((F[i-1]+2*i-1+mod)%mod-(T[i-1]%mod)+mod)%mod; S[i] = (S[i-1] + F[i])%mod; } } int main() { INIT(); LL n; int T; scanf("%d", &T); while(T--) { scanf("%lld", &n); printf("%lld\n", S[n]); } return 0; }