1. 程式人生 > >【Troywar love Maths】——莫比烏斯反演

【Troywar love Maths】——莫比烏斯反演

pen 輸出格式 targe div -h prim 沒有 .cn color

          2816. Troywar loves Maths

                ★★☆ 輸入文件:Troy_1.in 輸出文件:Troy_1.out 簡單對比
                        時間限制:1 s 內存限制:256 MB

【題目描述】

眾所周知,Troywar總是不好好上課看數(xiao)論(shuo)。一天數學老師是在看不下去了,於是決定考(jiao)考(xun)他一下。於是,扔給了Troywar一個問題:給定兩個正整數n和m,有多少對1<=i<=n,1<=j<=m使得$a=2^{i}+1,b=2^{j}+1$滿足a和b的最大公約數為3。翹課的Troywar當然不會了,他只好求助你。

【輸入格式】

兩個正整數n,m

【輸出格式】

一個整數。

【樣例輸入】

10 10

【樣例輸出】

19

【數據範圍】

1.10% n,m<=63

2.另有20%數據保證n,m<=1000

3.另有20%數據保證n<=3

4.對於所有數據,保證n,m<=1e7

【來源】

Troywar

題解:

   第一次出題,也不知道有沒有人做……我們先把n調成n,m中小的,m為較大的。

$\sum_{i=1}^{n}\sum_{j=1}^{m}[\gcd(2^{i}+1,2^{j}+1)==3]$


$首先,我們的要求是3|2^{x}+1$


$2^x+1\equiv 2^{x\,\bmod \phi(3)}+1(\bmod)3$
$所以當x為奇數時才可能成立,先令i>j$

$\;\;\;\;\gcd(2^{i}+1,2^{j}+1)=\gcd(2^{i}-2^{j},2^j+1)$
$=\gcd(2^{i-j}-1,2^j+1)$
$=\gcd (2^{i-j}+2^j,2^j+1)$

$若i-j>j$
$\gcd(2^{i}+1,2^{j}+1)=\gcd(2^{i-2j}+1,2^j+1)$
$否則$
$\gcd(2^{i}+1,2^{j}+1)=\gcd(2^{2j-i}+1,2^j+1)$
$聯系輾轉相除$
$\gcd(2^{i}+1,2^{j}+1)=2^{\gcd(i,j)}+1$


$所以有gcd(i,j)==1且i、j為奇數$

$\therefore Ans=\sum_{i=1}^{n}\sum_{j=1}^{m}[\gcd(i,j)==1\&i、j為奇數] $

$=\sum_{i=1}^{n}\sum_{j=1}^{m}[gcd(i,j)==1]-\sum_{i=1}^{\lfloor \frac n 2\rfloor}\sum_{j=1}^{m}[gcd(i,j)==1]-\sum_{i=1}^{\lfloor \frac m 2\rfloor}\sum_{j=1}^{n}[gcd(i,j)==1]$

$=\sum_{d=1}^{n}\mu(d)\lfloor \frac m d\rfloor\lfloor \frac n d\rfloor-\sum_{d=1}^{n}\mu(d)\lfloor \frac m d\rfloor\lfloor \frac n {kd}\rfloor-\sum_{d=1}^{n}\mu(d)\lfloor \frac m {kd}\rfloor\lfloor \frac n d\rfloor$

$其中當d為奇數時,k為2,否則k為1$

標程:

  

 1 #define Troy 09/29/2017
 2 
 3 #include<bits/stdc++.h>
 4 
 5 using namespace std;
 6 
 7 typedef long long ll;
 8 
 9 
10 const int N=1e7+1;
11 
12 int miu[N],prim[N/5],num,sum[N];
13 bool vis[N];
14 
15 inline void init(){
16     miu[1]=1;
17     sum[1]=1;
18     for(int i=2;i<N;i++){
19         if(!vis[i])
20             prim[++num]=i,miu[i]=-1;
21         for(int j=1;prim[j]*i<N;j++){
22             vis[i*prim[j]]=1;
23             if(i%prim[j]==0){
24                 miu[i*prim[j]]=0;
25                 break;
26             }
27             miu[i*prim[j]]=-miu[i];
28         }
29         sum[i]=sum[i-1]+miu[i];
30     }
31 }
32 
33 int n,m;
34 
35 int main(){ init();
36     freopen("Troy_1.in", "r", stdin);
37     freopen("Troy_1.out","w",stdout);
38     scanf("%d%d",&n,&m);
39     if(n>m) n^=m^=n^=m;
40     ll ans=0;
41     for(int i=1;i<=n;i++){
42         ll t=1ll*miu[i]*(n/i)*(m/i),d;
43         if(i&1){
44             d=1ll*miu[i]*(1ll*(n/i)*(m/i/2)+1ll*(n/i/2)*(m/i));
45         }
46         else    
47             d=1ll*2*miu[i]*(n/i)*(m/i);
48         ans+=t-d;
49     }
50     printf("%lld\n",ans);
51 }

【Troywar love Maths】——莫比烏斯反演