mr_dot_convict

808F-Card-Game-codeforces-mr.convict

Mar 30th, 2020
92
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.93 KB | None | 0 0
  1. // Hack it and have it ;) //
  2. /*author* Priyanshu Shrivastav (from IIT Palakkad) *
  3.  * *_ __ ___  _ ______ ___  _ ____   ___  ___| |_  *
  4.  * | '_ ` _ \| '__/ __/ _ \| '_ \ \ / / |/ __| __| *
  5.  * | | | | | | | | (_| (_) | | | \ V /| | (__| |_  *
  6.  * |_| |_| |_|_|(_)___\___/|_| |_|\_/ |_|\___|\__| *
  7. When I wrote this, only God and I understood what I was doing
  8.  ** * * * * * * * Now, only God knows!* * * * * * */
  9. #include      <bits/stdc++.h> /*{{{*/
  10. #include      <ext/pb_ds/assoc_container.hpp>
  11. #include      <ext/pb_ds/tree_policy.hpp>
  12. using namespace std;
  13. using namespace __gnu_pbds;
  14.  
  15. #ifndef CONVICTION
  16. #pragma GCC       optimize ("Ofast")
  17. #pragma GCC       optimize ("unroll-loops")
  18. #pragma GCC       target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
  19. #endif
  20.  
  21. #define IOS       ios_base::sync_with_stdio(false); cin.tie (nullptr)
  22. #define PREC      cout.precision (10); cout << fixed
  23. #define X         first
  24. #define Y         second
  25. #define sz(x)     (int)x.size()
  26. #define fr(i,x,y) for (int i = (int)x; i <= (int)y; ++i)
  27. #define rv(i,x,y) for (int i = (int)x; i >= (int)y; --i)
  28. // #define cnt(x)    __builtin_popcount(x)
  29. // #define cntll(x)  __builtin_popcountll(x)
  30. #define bg(x)     " [ " << #x << " : " << (x) << " ] "
  31. #define un(x)     sort(x.begin(), x.end()), \
  32.   x.erase(unique(x.begin(), x.end()), x.end())
  33. using   ll  =     long long;
  34. using   ull =     unsigned long long;
  35. using   ff  =     long double;
  36. using   pii =     pair<int,int>;
  37. using   pil =     pair<int,ll>;
  38. using   pll =     pair<ll,ll>;
  39. using   vi  =     vector <int>;
  40. using   vl  =     vector<ll>;
  41. using   vvi =     vector <vi>;
  42. using   vvl =     vector <vl>;
  43. using   vp  =     vector <pii>;
  44. using   vvp =     vector <vp>;
  45. typedef tree
  46. < int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update>
  47. ordered_set;
  48.  
  49. struct chash {
  50.   int operator () (pii x) const { return x.X*31 + x.Y; }
  51. };
  52. gp_hash_table <pii, int, chash> gmp;
  53.  
  54. #if __cplusplus > 201103L
  55. seed_seq seq{
  56.   (uint64_t) chrono::duration_cast<chrono::nanoseconds>
  57.     (chrono::high_resolution_clock::now().time_since_epoch()).count(),
  58.     (uint64_t) __builtin_ia32_rdtsc(),
  59.     (uint64_t) (uintptr_t) make_unique<char>().get()
  60. };
  61. mt19937 rng(seq); //uniform_int_distribution<int> (l, h)(rng); //[low, high]
  62. #else
  63. auto seed = chrono::high_resolution_clock::now().time_since_epoch().count();
  64. mt19937 rng(seed);
  65. #endif
  66.  
  67. #define debug(args...) { \
  68.   /* WARNING : do NOT compile this debug func calls with following flags: // \
  69.    * // -D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC -D_FORTIFY_SOURCE=2*/ \
  70.   string _s = #args; replace(_s.begin(), _s.end(), ',', ' ');\
  71.   stringstream _ss(_s); \
  72.   istream_iterator<string> _it(_ss); err(_it, args); \
  73. }
  74. void err(istream_iterator<string> it) {
  75.   it->empty(); cerr << " (Line : " << __LINE__ << ")" << '\n';
  76. }
  77. template<typename T, typename... Args>
  78. void err(istream_iterator<string> it, T a, Args... args) {
  79.   cerr << fixed << setprecision(15)
  80.     << " [ " <<  *it << " : " << a  << " ] "<< ' ';
  81.   err(++it, args...);
  82. }
  83. //         __                                           __
  84. //        (**)                                         (**)
  85. //        IIII                                         IIII
  86. //        ####                                         ####
  87. //        HHHH     Madness comes, and madness goes     HHHH
  88. //        HHHH    An insane place, with insane moves   HHHH
  89. //        ####   Battles without, for battles within   ####
  90. //     ___IIII___        Where evil lives,          ___IIII___
  91. //  .-`_._"**"_._`-.      and evil rules         .-`_._"**"_._`-.
  92. // |/``  .`\/`.  ``\|    Breaking them up,      |/``  .`\/`.  ``\|
  93. // `     }    {     '  just breaking them in    `     }    {     '
  94. //       ) () (  Quickest way out, quickest way wins  ) () (
  95. //       ( :: )      Never disclose, never betray     ( :: )
  96. //       | :: |   Cease to speak or cease to breath   | :: |
  97. //       | )( |        And when you kill a man,       | )( |
  98. //       | || |          you're a murderer            | || |
  99. //       | || |             Kill many                 | || |
  100. //       | || |        and you're a conqueror         | || |
  101. //       | || |        Kill them all ... Ooh..        | || |
  102. //       | || |           Oh you're a God!            | || |
  103. //       ( () )                       -Megadeth       ( () )
  104. //        \  /                                         \  /
  105. //         \/                                           \/
  106. /*}}}*/
  107. /*****************************************************************************/
  108. //Don’t practice until you get it right. Practice until you can’t get it wrong
  109.  
  110. const int MAX_P = 2101000;
  111. set <int> primes = {2}, powers;
  112. void sieve() {
  113.   vector <bool> isPrime(MAX_P + 1, true);
  114.   for (int i = 3; i*2 <= MAX_P; i += 2) {
  115.     int p = 0;
  116.     while (1ll * i*(i + p) <= MAX_P) isPrime[i*(i + p)] = false, ++p;
  117.   }
  118.   for (int i = 3; i <= MAX_P; i += 2) {
  119.     if (isPrime[i]) primes.insert(i);
  120.   }
  121. }
  122. const int N = 110;
  123. const int infi = (int)1e9;
  124. int f[N][N];
  125. vector < vector <int> > Adj;
  126. int Par[N];
  127. int V;
  128.  
  129. int bfs (int s, int t) {
  130.    fill (Par, Par + V, -1);
  131.    Par[s] = -2;
  132.  
  133.    queue <pii> Q;
  134.    Q.push(pii(s, infi));
  135.  
  136.    while (!Q.empty()) {
  137.       pii tmp = Q.front();
  138.       Q.pop();
  139.       int u = tmp.first, flow = tmp.second;
  140.  
  141.       for (int v : Adj[u]) {
  142.          if (Par[v] == -1 && f[u][v]) {
  143.             Par[v] = u;
  144.             int newFlow = min(flow, f[u][v]);
  145.             if (v == t) {
  146.                return newFlow;
  147.             }
  148.             Q.push(pii(v, newFlow));
  149.          }
  150.       }
  151.    }
  152.    return 0;
  153. }
  154.  
  155. int edmondsKarp(int s, int t) {
  156.    int flow = 0;
  157.    int newFlow;
  158.  
  159.    while ((newFlow = bfs (s, t))) {
  160.       flow += newFlow;
  161.       int cur = t;
  162.       while (cur != s) {
  163.          int prv = Par[cur];
  164.          f[prv][cur] -= newFlow;
  165.          f[cur][prv] += newFlow;
  166.          cur = prv;
  167.       }
  168.    }
  169.    return flow;
  170. }
  171.  
  172. inline void addEdge(int u, int v, int flow) {
  173.    Adj[u].push_back(v);
  174.    Adj[v].push_back(u);
  175.    f[u][v] = flow;
  176. }
  177.  
  178. struct Card { int idx, p, c, l; };
  179. vector <Card> cards, ones;
  180. int n;
  181.  
  182. void init() {
  183.   V = n + 2;
  184.   Adj.assign(V, vector <int> ());
  185.   for (int i = 0; i < V; ++i) for (int j = 0; j < V; ++j)
  186.     f[i][j] = 0;
  187. }
  188.  
  189. int solve (int lvl) {
  190.   init();
  191.   int sm = 0, idx = -1;
  192.   for (int i = 0, mx = 0; i < (int)ones.size(); ++i) {
  193.     if (ones[i].l <= lvl && mx <= ones[i].p) idx = i, mx = max(mx, ones[i].p);
  194.   }
  195.  
  196.   if (idx != -1) {
  197.     sm += ones[idx].p;
  198.     addEdge(n, ones[idx].idx, ones[idx].p);
  199.     for (int i = 0; i < (int)cards.size(); ++i) {
  200.       if (primes.find(ones[idx].c + cards[i].c) != primes.end()) {
  201.        addEdge(ones[idx].idx, cards[i].idx, infi);
  202.       }
  203.     }
  204.   }
  205.  
  206.   for (int i = 0; i < (int)cards.size(); ++i) { // source and sink
  207.     if (cards[i].l <= lvl) {
  208.       sm += cards[i].p;
  209.       if (cards[i].c & 1) addEdge(n, cards[i].idx, cards[i].p);
  210.       else addEdge(cards[i].idx, n + 1, cards[i].p);
  211.     }
  212.   }
  213.  
  214.   for (int i = 0; i < (int)cards.size(); ++i) { // between two
  215.     if (cards[i].l <= lvl) {
  216.       for (int j = i + 1; j < (int)cards.size(); ++j) {
  217.         if (cards[j].l <= lvl) {
  218.           if (primes.find(cards[i].c + cards[j].c) != primes.end()) {
  219.             if (cards[i].c & 1) addEdge(cards[i].idx, cards[j].idx, infi);
  220.             else addEdge(cards[j].idx, cards[i].idx, infi); }
  221.         }
  222.       }
  223.     }
  224.   }
  225.   int res = (int) edmondsKarp(n, n + 1);
  226.   return sm - res;
  227. }
  228.  
  229.  
  230. signed main() {
  231.   IOS; PREC;
  232.   sieve();
  233.   int k;
  234.   cin >> n >> k;
  235.   for (int i = 0; i < n; ++i) {
  236.     int p, c, l;
  237.     cin >> p >> c >> l;
  238.     if (c == 1) ones.push_back({i, p, c, l});
  239.     else cards.push_back({i, p, c, l});
  240.   }
  241.  
  242.   int l = 1, h = n;
  243.  
  244.   while (l <= h) {
  245.     int g = (l + h) / 2;
  246.     int res = solve(g);
  247.     if (res >= k) {
  248.       h = g - 1;
  249.     }
  250.     else l = g + 1;
  251.   }
  252.   if (l > n) cout << -1 << "\n";
  253.   else cout << l << '\n';
  254.  
  255.  
  256.   return EXIT_SUCCESS;
  257. }
Add Comment
Please, Sign In to add comment