BZOJ3308 九月的咖啡店

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 }
View Code

(p.s. 成功成为最慢的2333)

转载于:https://www.cnblogs.com/rausen/p/4507582.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值