莫比乌斯反演模版
//--莫比乌斯反演函数--// //说明:利用线性素数筛选顺便求了个mu //注释部分为求从区间[1,b]和区间[1,d]中取两个数,互质对数O(n^0.5) //复杂度:O(n) int mu[N]; //int sum[N]; void mobus() { bool mark[N]; int prime[N]; int pcnt=0; memset(mark,0,sizeof(mark)); mu[1] = 1; for(int i=2;i<N;i++) { if(mark[i] == 0) { prime[pcnt++] = i; mu[i] = -1; } for(int j=0;j<pcnt && i*prime[j]<N;j++) { int tmp = i*prime[j]; mark[tmp] = 1; if( i%prime[j] == 0 ) { mu[tmp] = 0; break; } mu[tmp] = mu[i]*-1; } } // for(int i=1;i<N;i++) // sum[i] += sum[i-1]+mu[i]; } //long long gaobili(int b,int d) //{ // if(b<=0||d<=0) return 0; // int m = min(b,d); // long long ans = 0; // while(m>=1) // { // int tb = b/( b/m +1 )+1; // int td = d/( d/m +1 )+1; // //前进的最大位置 // int tm = max(tb,td); // ans += (long long)(sum[m]-sum[tm-1])*(b/m)*(d/m); // m = tm-1; // } // return ans; //}
代码量超少的求一些特别情况的mobus,复杂度O( nlog(n) )
for (int i = 1; i <= n; i++) g[i] = f[i]; for (int i = 1; i <= n; i++) for (int j = i + i; j <= n; j += i) g[j] -= g[i];