HDU6760 Math is Simple 数学变形+莫比乌斯反演

题目描述


∑ 1 ≤ a ≤ b ≤ n , g c d ( a , b ) = 1 , a + b ≥ n 1 a b \sum\limits_{1\leq a \le b \leq n,gcd(a,b)=1,a+b \geq n}\frac{1}{ab} 1abn,gcd(a,b)=1,a+bnab1
1 ≤ T ≤ 1 e 4 , 1 ≤ N ≤ 1 e 8 1 \leq T \leq 1e4 , 1\leq N \leq 1e8 1T1e4,1N1e8

分析

a + b ≥ n a+b \geq n a+bn,所以考虑和前一项作差。
f n = ∑ 1 ≤ a < b ≤ n , g c d ( a , b ) = 1 , a + b ≥ n 1 a b f_n = \sum\limits_{1\leq a < b \leq n,gcd(a,b)=1,a+b \geq n}\frac{1}{ab} fn=1a<bn,gcd(a,b)=1,a+bnab1
作差之后,少了个 a + b = n − 1 a+b = n-1 a+b=n1,多了个 b = n b=n b=n即:
f n = f n − 1 + ∑ 1 ≤ a < n , g c d ( a , n ) = 1 1 a n − ∑ 1 ≤ a < b ≤ n , g c d ( a , b ) = 1 , a + b = n − 1 1 a b f_n = f_{n-1} + \sum\limits_{1 \leq a < n,gcd(a,n)=1} \frac{1}{an} - \sum\limits_{1\leq a < b \leq n,gcd(a,b)=1,a+b = n-1}\frac{1}{ab} fn=fn1+1a<n,gcd(a,n)=1an11a<bn,gcd(a,b)=1,a+b=n1ab1
发现对于后面-的部分,设为 g n g_n gn有:
g n = ∑ 1 ≤ a < b ≤ n , g c d ( a , b ) = 1 , a + b = n 1 a b = 1 n ∑ 1 ≤ a < b ≤ n , g c d ( a , b ) = 1 , a + b = n 1 a + 1 b = 1 n ∑ 1 ≤ a < n , g c d ( a , n ) = 1 1 a g_n=\sum\limits_{1\leq a < b \leq n,gcd(a,b)=1,a+b = n}\frac{1}{ab} = \frac{1}{n}\sum\limits_{1\leq a < b \leq n,gcd(a,b)=1,a+b = n} \frac{1}{a} + \frac{1}{b} = \frac{1}{n}\sum\limits_{1\leq a < n,gcd(a,n)=1} \frac{1}{a} gn=1a<bn,gcd(a,b)=1,a+b=nab1=n11a<bn,gcd(a,b)=1,a+b=na1+b1=n11a<n,gcd(a,n)=1a1
且上面式子的 n ≥ 3 n\geq 3 n3,当 n = 2 n=2 n=2时, g 2 = 0 g_2 = 0 g2=0
发现跟前面那一项长的差不多,其实就是有:
f n = f n − 1 + g n − g n − 1 f_n= f_{n-1} + g_n-g_{n-1} fn=fn1+gngn1
f n − 1 f_{n-1} fn1再裂开,我们就有 f n = f 2 + g n − g 2 = 1 2 + g n f_n = f_2 + g_n - g_2 = \frac{1}{2} + g_n fn=f2+gng2=21+gn
对于 g n g_n gn,有:
g n = 1 n ∑ i = 1 n 1 i ∑ d ∣ g c d ( i , n ) μ ( d ) = 1 n ∑ d ∣ n μ ( d ) d S ( ⌊ n d ⌋ ) g_n = \frac{1}{n} \sum\limits_{i=1}^{n} \frac{1}{i}\sum\limits_{d|gcd(i,n)} \mu(d) = \frac{1}{n}\sum\limits_{d|n} \frac{\mu(d)}{d}S(\lfloor \frac{n}{d} \rfloor) gn=n1i=1ni1dgcd(i,n)μ(d)=n1dndμ(d)S(dn)
然后开一个 1 e 8 1e8 1e8的数组,需要 380 M B 380MB 380MB的空间,所以我们可以预处理前缀和,然后对于每个 n n n进行质因数分解,然后二进制枚举质因数即可。

代码

#include 

#define rep(i,a,b) for(int i=(a);i<=(b);++i)
#define dep(i,a,b) for(int i=(a);i>=(b);--i)
#define fi first
#define se second
#define CL clear
#define MP make_pair
#define PB push_back

//#define int long long

const int N = (int) 1e8 + 10;
const int mod = (int) 998244353;

using namespace std;

typedef long long ll;

inline int rd() {
  int p=0; int f=1; char ch=getchar();
  while(ch<'0' || ch>'9'){if(ch=='-') f*=-1; ch=getchar();}
  while(ch>='0' && ch<='9'){p=p*10+ch-'0'; ch=getchar();}
  return p*f;
}

int inv[N];

ll qpow(ll x,ll k,ll mo) {
  ll s = 1;
  while(k) {
    if(k&1) s=1ll*s*x%mo;
    x=1ll*x*x%mo; k>>=1;
	}return s;
}

vector<ll> fac;

signed main() {
  
  inv[0] = inv[1] = 1;
  for(int i=2;i<=(int)(1e8);++i) inv[i] = (ll)(mod - mod / i) * inv[mod % i] % mod;
  for(int i=2;i<=(int)(1e8);++i) inv[i] = (inv[i-1] + inv[i]) % mod;
  int t = rd();
  while(t--) {
    ll n = rd(); ll ans = qpow(2,mod-2,mod); ll x = n;
    fac.CL(); for(ll i=2;i*i<=x;++i) if(x%i == 0) {
      fac.PB(i);
      while(x%i==0) x/=i;
	  }if(x!=1) fac.PB(x);
	  ll gn = 0;
	  if(n>2) {
	    for(ll i=0;i<(1<<fac.size());++i) {
	      ll d = 1; ll s = 0;
			  for(ll j=0;j<fac.size();++j) if(i&(1<<j)){
			  	d *= fac[j]; s++;
	      }
	      gn = (gn + 1ll * ((s&1) ? (-1) : 1) * qpow(d,mod-2,mod) % mod * inv[n/d] % mod) % mod;
		  }gn = gn * qpow(n , mod-2 , mod) % mod;
	  }else gn = 0;
	  printf("%lld\n",(ans + gn + mod) % mod);
	}
  return 0;
}

你可能感兴趣的:(hdu,数学,莫比乌斯反演)