1. 程式人生 > >[BZOJ 2790] [POI 2012] Distance

[BZOJ 2790] [POI 2012] Distance

實現 getchar() true return 最小步數 mem 條件 bsp distance

題意

  給定長度為 n 的序列 a[1], a[2], ..., a[n] .

  對於每個數 i , 求出 j , 滿足 dist(a[i], a[j]) 最小, 且 i != j .

  dist(x, y) 表示由 x 變為 y 的最小步數, 每次變換可以乘上素數 p , 或除以素數 p .

  2 <= n <= 100000 , 1 <= a[i] <= 1000000 .

分析

  從前往後掃一遍, 從後往前掃一遍, 來滿足 i != j 的條件.

  記 Min[i] 表示訪問到點 i 的最小步數, 通過枚舉質因子, 維護 Min[i] 並更新答案.

實現

 1 #include <cstdio>
 2
#include <cstring> 3 #include <cstdlib> 4 #include <cctype> 5 #include <algorithm> 6 using namespace std; 7 #define F(i, a, b) for (register int i = (a); i <= (b); i++) 8 #define D(i, a, b) for (register int i = (a); i >= (b); i--) 9 inline int rd(void) { 10 int
f = 1; char c = getchar(); for (; !isdigit(c); c = getchar()) if (c == -) f = -1; 11 int x = 0; for (; isdigit(c); c = getchar()) x = x*10+c-0; return x*f; 12 } 13 inline void gmin(pair<int, int> &x, pair<int, int> y) { x = min(x, y); } 14 15 const int N = 100005; 16 const int M = 1000000
; 17 const int INF = ~0u>>2; 18 19 bool v[M+5]; int pri[M+5], tot, cnt[M+5]; 20 int n, a[N]; 21 pair<int, int> Min[M+5], ans[N], tmp[N]; 22 23 void Oper(int i) { 24 for (int x = 1; x * x <= a[i]; x++) if (a[i] % x == 0) { 25 if (Min[x] != make_pair(INF, -1)) 26 gmin(ans[i], make_pair(Min[x].first + cnt[a[i] / x], Min[x].second)); 27 if (Min[a[i] / x] != make_pair(INF, -1)) 28 gmin(ans[i], make_pair(Min[a[i] / x].first + cnt[x], Min[a[i] / x].second)); 29 } 30 for (int x = 1; x * x <= a[i]; x++) if (a[i] % x == 0) { 31 gmin(Min[x], make_pair(cnt[a[i] / x] , i)); 32 gmin(Min[a[i] / x], make_pair(cnt[x], i)); 33 } 34 } 35 36 int main(void) { 37 #ifndef ONLINE_JUDGE 38 freopen("bzoj2790.in", "r", stdin); 39 #endif 40 41 v[1] = true; 42 F(i, 2, M) { 43 if (!v[i]) pri[++tot] = i, cnt[i] = 1; 44 for (int j = 1; j <= tot && i * pri[j] <= M; j++) { 45 v[i * pri[j]] = true, cnt[i * pri[j]] = cnt[i] + 1; 46 if (i % pri[j] == 0) break; 47 } 48 } 49 50 n = rd(); 51 F(i, 1, n) a[i] = rd(); 52 53 F(i, 1, n) ans[i] = make_pair(INF, -1); 54 F(i, 1, M) Min[i] = make_pair(INF, -1); 55 F(i, 1, n) 56 Oper(i); 57 58 memcpy(tmp, ans, sizeof ans); 59 F(i, 1, n) ans[i] = make_pair(INF, -1); 60 F(i, 1, M) Min[i] = make_pair(INF, -1); 61 D(i, n, 1) 62 Oper(i); 63 64 F(i, 1, n) printf("%d\n", min(tmp[i], ans[i]).second); 65 66 return 0; 67 }

[BZOJ 2790] [POI 2012] Distance