1. 程式人生 > >BZOJ2440(容斥+莫比烏斯函數)

BZOJ2440(容斥+莫比烏斯函數)

tdi -- lse algorithm prime getc ima bzoj 莫比烏斯函數

題目本質:

技術分享圖片

首先有如下結論:

技術分享圖片

而通過寫一寫可以發現:

舉例來講,36及其倍數的數,會被1的倍數加一遍,被4的倍數扣一遍,會被9的倍數扣一遍,而為了最終計數為0,需要再加回來一遍,所以在容斥裏面是正號。

對於36有:6 = 2 * 3,mu[6] = 1;而同時對比16有:4 = 2 * 2,mu[4] = 0;9有:3 = emmm,mu[3] = -1。

枚舉到2時,2*2的倍數被扣一遍;枚舉到3時,3*3的倍數被扣一遍;枚舉到4時,因為它最終只需要扣一遍,而現在已經滿足了,所以跳過;枚舉到6時,6*6的倍數因為被2和3分別扣過一次,這次要加回來……故可以發現,這個減去還是加上還是不動的選擇,剛好與此數的mu值相同。

代碼不是主要問題:

  1 #pragma comment(linker, "/STACK:1024000000,1024000000")
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <cstdlib>
  5 #include <cmath>
  6 #include <ctime>
  7 #include <cctype>
  8 #include <climits>
  9 #include <iostream>
 10
#include <iomanip> 11 #include <algorithm> 12 #include <string> 13 #include <sstream> 14 #include <stack> 15 #include <queue> 16 #include <set> 17 #include <map> 18 #include <vector> 19 #include <list> 20 #include <fstream> 21
#include <bitset> 22 #define init(a, b) memset(a, b, sizeof(a)) 23 #define rep(i, a, b) for (int i = a; i <= b; i++) 24 #define irep(i, a, b) for (int i = a; i >= b; i--) 25 using namespace std; 26 27 typedef double db; 28 typedef long long ll; 29 typedef unsigned long long ull; 30 typedef pair<int, int> P; 31 const int inf = 0x3f3f3f3f; 32 const ll INF = 1e18; 33 34 template <typename T> void read(T &x) { 35 x = 0; 36 int s = 1, c = getchar(); 37 for (; !isdigit(c); c = getchar()) 38 if (c == -) s = -1; 39 for (; isdigit(c); c = getchar()) 40 x = x * 10 + c - 48; 41 x *= s; 42 } 43 44 template <typename T> void write(T x) { 45 if (x < 0) x = -x, putchar(-); 46 if (x > 9) write(x / 10); 47 putchar(x % 10 + 0); 48 } 49 50 template <typename T> void writeln(T x) { 51 write(x); 52 puts(""); 53 } 54 55 const int maxn = 1e5; 56 int mu[maxn], primes[maxn], tot; 57 bool vis[maxn]; 58 59 void pre(int n) { 60 mu[1] = 1; 61 rep(i, 2, n) { 62 if (!vis[i]) { 63 mu[i] = -1; 64 primes[++tot] = i; 65 } 66 for (int j = 1; j <= tot && primes[j] * i <= n; j++) { 67 vis[primes[j] * i] = true; 68 if (i % primes[j] == 0) break; 69 mu[primes[j] * i] = -mu[i]; 70 } 71 } 72 } 73 74 int cal(int x) { 75 int m = sqrt(x), res = 0; 76 rep(i, 1, m) { 77 res += mu[i] * (x / (i * i)); 78 } 79 return res; 80 } 81 82 int solve(int n) { 83 int l = 1, r = 2 * n, ans; 84 while (l <= r) { 85 int mid = (1ll * l + r) >> 1; 86 int k = cal(mid); 87 if (k >= n) ans = mid, r = mid - 1; 88 else l = mid + 1; 89 } 90 return ans; 91 } 92 93 int main() { 94 pre(maxn); 95 int T, n; 96 for (read(T); T; T--) { 97 read(n); 98 writeln(solve(n)); 99 } 100 return 0; 101 }

BZOJ2440(容斥+莫比烏斯函數)