Orz PoPoQQQ
话说这题还有要注意的地方。。。
就是。。。不能加SLF优化,千万不能加
n = 40000,不加本机跑出来2sec,加了跑出来40sec。。。【给跪了
1 /************************************************************** 2 Problem: 3308 3 User: rausen 4 Language: C++ 5 Result: Accepted 6 Time:27500 ms 7 Memory:32752 kb 8 ****************************************************************/ 9 10 #include <cstdio> 11 #include <algorithm> 12 #include <bitset> 13 14 using namespace std; 15 const int N = 2e4 + 5; 16 const int Cnt = N * 10; 17 const int M = Cnt * 10; 18 const int inf = 1e9; 19 20 struct edges { 21 int next, to, f, cost; 22 edges() {} 23 edges(int _n, int _t, int _f, int _c) : next(_n), to(_t), f(_f), cost(_c) {} 24 } e[M]; 25 26 int n, ans, S, T; 27 int first[N], tot = 1; 28 bitset <Cnt> not_p; 29 int pr[N], tot_p, tot_a, tot_b; 30 int d[N], g[N], v[N]; 31 32 inline void Add_Edges(int x, int y, int f, int c) { 33 e[++tot] = edges(first[x], y, f, c), first[x] = tot; 34 e[++tot] = edges(first[y], x, 0, -c), first[y] = tot; 35 } 36 37 inline void calc() { 38 static int x; 39 for (x = g[T]; x; x = g[e[x ^ 1].to]) 40 --e[x].f, ++e[x ^ 1].f; 41 } 42 43 #define y e[x].to 44 inline bool spfa() { 45 static int x, now, q[70000]; 46 static unsigned short l, r; 47 for (x = 1; x <= T; ++x) 48 d[x] = -inf; 49 d[S] = 0, v[S] = 1, q[0] = S; 50 for(l = r = 0; l != r + 1; ) { 51 now = q[l++]; 52 for (x = first[now]; x; x = e[x].next) { 53 if (e[x].f && d[now] + e[x].cost > d[y]) { 54 d[y] = d[now] + e[x].cost, g[y] = x; 55 if (!v[y]) 56 v[y] = 1, q[++r] = y; 57 } 58 } 59 v[now] = 0; 60 } 61 return d[T] >= 0; 62 } 63 #undef y 64 65 inline int work() { 66 int res = 0; 67 while (spfa()) 68 calc(), res += d[T]; 69 return res; 70 } 71 72 void get_prime(int N) { 73 int i, j, k; 74 for (i = 2; i <= n; ++i) { 75 if (!not_p[i]) pr[++tot_p] = i; 76 for (j = 1; j <= tot_p; ++j) { 77 if ((k = i * pr[j]) > N) break; 78 not_p[k] = 1; 79 if (i % pr[j] == 0) break; 80 } 81 } 82 } 83 84 inline int get(int n, int p) { 85 static int res; 86 for (res = 1; res * p <= n; res *= p); 87 return res; 88 } 89 90 int main() { 91 int i, j, tmp; 92 scanf("%d", &n); 93 get_prime(n); 94 for (i = 1; i <= tot_p && 1ll * pr[i] * pr[i] <= n; ++i) ++tot_a; 95 for (; i <= tot_p && pr[i] * 2 <= n; ++i) ++tot_b; 96 for (; i <= tot_p; ++i) ans += pr[i]; 97 S = tot_a + tot_b + 1, T = S + 1; 98 99 #define J j + tot_a 100 for (i = 1; i <= tot_a; ++i) 101 Add_Edges(S, i, 1, 0), Add_Edges(i, T, 1, get(n, pr[i])); 102 for (j = 1; j <= tot_b; ++j) 103 Add_Edges(S, J, 1, pr[J]), Add_Edges(J, T, 1, 0); 104 for (i = 1; i <= tot_a; ++i) 105 for (j = 1; j <= tot_b; ++j) 106 if ((tmp = get(n / pr[J], pr[i]) * pr[J]) > get(n, pr[i]) + pr[J]) 107 Add_Edges(i, J, 1, tmp); 108 #undef J 109 printf("%d\n", ans + 1 + work()); 110 return 0; 111 }
(p.s. 成功成为最慢的2333)