标签:表示 include print using emc mem names 条件 长度
给定长度为 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
标签:表示 include print using emc mem names 条件 长度
原文地址:http://www.cnblogs.com/Sdchr/p/7517734.html