LOJ#2085. 「NOI2016」循环之美 莫比乌斯反演+杜教筛


求:$\sum_{i=1}^{n} \sum_{j=1}^{m} [(i,j)=1][(j,k)=1]$

这个时候可以拆前面的,也可以拆后面的.

由于后面的 $k$ 是一个定值,考虑拆解后面的部分.

得:$\sum_{d|k} \mu(d) \sum_{i=1}^{n} \sum_{j=1}^{\frac{m}{d}} [(i,jd)=1]$

$\Rightarrow \sum_{d|k} \mu(d) \sum_{i=1}^{n} \sum_{j=1}^{\frac{m}{d}} [(i,j)=1][(i,d)=1]$

令 $S(n,m,k)=\sum_{i=1}^{n} \sum_{j=1}^{m} [(i,j)=1][(j,k)=1]$

则有 $S(n,m,k)=\sum_{d|k} \mu(d)S(\frac{m}{d},n,d)$

其中边界条件是 $n,m \leqslant 0$ 和 $k=1$.

$k=1$ 时求的是 $\sum_{i=1}^{n} \sum_{j=1}^{m} [(i,j)=1]$

也就是 $\sum_{d=1}^{\min(n,m)} \mu(d)\frac{n}{d}\frac{m}{d}$

这个需要用到杜教筛来计算 $\mu$ 的前缀和.

$\Rightarrow S(n)=\frac{\sum_{i=1}^{n}(f*g)(i)-\sum_{i=2}^{n}S(\frac{n}{i})g(i)}{g(1)}$

我们选 $g=I(x)$,则 $(f*g)(i)=[i=1]$.

则 $S(n)=1-\sum_{i=2}^{n} S(\frac{n}{i})$

时间复杂度不会计算,但是跑的挺快.

代码:

#include 
#include 
#include 
#include 
#include  
#define N 20000008 
#define ll long long 
#define pb push_back  
#define setIO(s) freopen(s".in","r",stdin) 
using namespace std;
mapansmu;  
mapvised;    
vectorG[2003];  
int vis[N],mu[N],prime[N],sum[N],tot;  
void init() { 
	mu[1]=1;   
	for(int i=2;im) swap(n,m);  
	ll ans=0; 
	for(int i=1,j;i<=n;i=j+1)  { 
		j=min(n/(n/i),m/(m/i));  
		ans+=1ll*(n/i)*(m/i)*(getmu(j)-getmu(i-1));  
	}   
	return ans;  
}
ll solve(int n,int m,int k) {  
	if(n<=0||m<=0) return 0;   
	if(k==1) {   
		return calc(n,m);  
	}  
	ll ans=0;
	for(int i=0;i 
   

  

 

你可能感兴趣的:(LOJ#2085. 「NOI2016」循环之美 莫比乌斯反演+杜教筛)