Блог пользователя Shafaet

Автор Shafaet, история, 7 лет назад, По-английски

Hello Codeforces Community, I am glad to share HackerRank World Codesprint 11 starting on 26th May 2017. The contest duration is 24 * 2 =48 hours.

The winners of the contest will win up to 2000USD cash prizes. Also, there are opportunities to win T-shirts and Amazon Gift cards.

The contest will be rated. If two person gets the same score, the person who reached the score first will be ranked higher. There will be 7 algorithmic challenges in the contest including an approximate challenge.

The problems are prepared by svanidz1, tunyash, CMaster, muratt and Shafaet. Thanks to Wild_Hamster for testing the challenges and finalizing everything.

Update: Contest is starting in 10 minutes.

Update: The contest ended, congrats to the winners.

Happy Coding!

  • Проголосовать: нравится
  • +65
  • Проголосовать: не нравится

»
7 лет назад, # |
  Проголосовать: нравится +29 Проголосовать: не нравится

11

»
7 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

Auto comment: topic has been updated by Shafaet (previous revision, new revision, compare).

»
7 лет назад, # |
  Проголосовать: нравится +210 Проголосовать: не нравится

»
7 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

Approaches for the approximate problem? I used backtrack to solve the smallest tests optimally and greedy for the remaining tests — pick an order of the pieces and try to place them in a shaft of fixed width (either trying all possible widths or at least divisors of the optimum size) in that order either by trying various Tetris-style drops, all possible positions (only smaller tests) or making the leftmost bottom cell of the given piece coincide with the leftmost bottom free cell. It was pretty slow, so it scored about 2/3 points for the largest tests and over 0.8 for the rest.

»
7 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

Can you enable viewing of others solution?

»
7 лет назад, # |
  Проголосовать: нравится +6 Проголосовать: не нравится

Can someone share his approaches for the problem "The Best Mask" ? I went through the editorial and could not understand it.

  • »
    »
    7 лет назад, # ^ |
    Rev. 3   Проголосовать: нравится 0 Проголосовать: не нравится

    I went with recursion in index of a bit, starting with the lowest one. That is rather slow in the worst case, but one can cut off some of the recursion branches that are not promising.

    Every time we try to set a bit to 0, the set of the numbers that need to be matched with the mask stays the same, and if we set a bit to 1, all the numbers that have that bit set are taken care of, so on average, the set is cut in half.

    This is probably not much worse on average than the intended solution, but I am not so sure about possible hacks. I managed to get it to pass the test cases in barely under 1s.

    Code:
    • »
      »
      »
      7 лет назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится

      try this one:

      1
      67108864
      

      Just curious will this line gets RE at some test or not:

      assert(a[i] < (1 << 26));
      
      • »
        »
        »
        »
        7 лет назад, # ^ |
          Проголосовать: нравится 0 Проголосовать: не нравится

        None of the hackerrank tests for this problem contain numbers >=2^26, for 2^26 my code would probably fail.

»
7 лет назад, # |
  Проголосовать: нравится +20 Проголосовать: не нравится

Test case for the last problem is very bad. Bruteforce solution get > 96 points. :(

»
7 лет назад, # |
  Проголосовать: нравится +4 Проголосовать: не нравится

Can some one explain me the solution of the 4th problem? City Construction?

  • »
    »
    7 лет назад, # ^ |
      Проголосовать: нравится +10 Проголосовать: не нравится

    You need this observation to solve the problem City Construction:

    Future addition of nodes cannot change the answer for past queries

    That is, the answer remains the same whether you solve a query the moment it is given or you solve the query after considering all the updates. Let's see why this is true. There are two ways to add a node.

    1. The new node has a directed edge towards an old node. In this case, this new node can never be reachable from any old node no matter what the future updates are. Think for yourself why this is true

    2. The new node has a directed edge coming from an old node towards itself. In this case the new node can never reach any old node no matter what the future updates are. Again think for yourself.

    So now we have established that we can take all the updates at first and add the edges for each update and then process the queries. So now the problem becomes, given a directed graph, answer some queries like if it is possible to reach x from y?

    We can solve this problem using dp if the graph was acyclic i.e DAG. So we divide the graph into strongly connected components and build a new graph with those components which will indeed be a DAG. Now our definition for the dp will be:

    dp[i] = nodes which are reachable from node i

    And our recurrence will be:

    dp[i] = union of node i and all possible dp[j] where j is any node which can be reached from node i using one edge

    So the complexity would be O(N*M) This is because for every edge we have to union two sets each of which can have size as large as N. Think of dp array as an array of boolean arrays and you or two boolean arrays of size N for each edge.

    But instead of using a boolean array, you can use bitsets to optimize the solution to have a time complexity of O( ( N * M ) / log( number of bits in an integer ) which is basically ( ( 5*10^4 * 10^5 ) / 32 ) or simply around ( 1.7 * 10^8 ) operations which can easily pass under the time limit.

    Hope this helps.

»
7 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

I had used DFS for the problem city construction. None of the test cases passed. Then after optimizing my dfs so that it won't check for other nodes once its found this particular one stupid me thought that i'll pass some/possibly all cases. Still none passes :/.

Anyone with a similar logic who's passed the cases? I'd love some hints. Or has everyone thought of the way it's coded in the editorial?

  • »
    »
    7 лет назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится

    Did you run dfs on each query? This is O(n*q) and I don't think it can be optimized with bitsets in any way.

    The solution in editorial works fast only because of bitsets. It's something like O(n^2 / (bitset_constant)).

    • »
      »
      »
      7 лет назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится

      Nah, mate:)

      We're using bitsets ONLY because of constraints of memory. Bitset is obviously slower than vector/array.

      The solution in editorial is fast enough because of SCC (and non-complete tests).

      • »
        »
        »
        »
        7 лет назад, # ^ |
          Проголосовать: нравится 0 Проголосовать: не нравится

        I was talking more of the idea of bitsets than of the c++/java structure implementation. I believe that compressing bits using ints can be faster with vectors.

        Isn't there still up to 5·104 SCCs? Like are there any tests where author solution may perform for too long?

      • »
        »
        »
        »
        7 лет назад, # ^ |
          Проголосовать: нравится +5 Проголосовать: не нравится

        No, bitset OR is fast, so you can use dag topsort order to compute reachability by performing OR on children's reachable vertices. It is not only to save memory but also time.

»
7 лет назад, # |
Rev. 5   Проголосовать: нравится +10 Проголосовать: не нравится

Really weak testcases which makes me sad:(

In problem 'The Best Mask' (75 pts) I have AC with optimized N·226.

In problem 'Road Trip' (100 pts) I have 97 out of 100 with sorting queries and stupid n2 approach (I handle all queries with equal xi for linear time).

  • »
    »
    7 лет назад, # ^ |
    Rev. 10   Проголосовать: нравится 0 Проголосовать: не нравится

    I did the same as you. Additionally, I got a full score D 'City Construction' just by doing the following:

    • Group each node based on its SCC
    • For each SCC, run a DFS. If i-th component can visit j-th component, store that information in Map/Set.

    This solution is supposed to be quadratic in time and memory, yet passed all cases.

    • »
      »
      »
      7 лет назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится

      Now the funniest part of this. Quadratic approach in D is exactly what's in editorial (ofc with SCC but still quadratic).

    • »
      »
      »
      7 лет назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится

      At least your solution is not wrong :D

      My friend (or maybe, I don't know the word for this, let's call him my senpai :v) did it like this:

      • Group every node based on its SCC.

      • Run a DFS, number all component like in Euler tour for tree.

      • Use that numbering to check reachability (like in a tree).

      This, is completely wrong if the original graph doesn't form a SCC. Yet he got AC.

      • »
        »
        »
        »
        7 лет назад, # ^ |
          Проголосовать: нравится +8 Проголосовать: не нравится

        My apologies. I tried my best to generate good tests, but it wasn't enough according to this comment. I am sorry, if this made you sad.

        BTW, it was my first problem in hackerrank

        • »
          »
          »
          »
          »
          7 лет назад, # ^ |
            Проголосовать: нравится 0 Проголосовать: не нравится

          It happens, good luck next time:)

        • »
          »
          »
          »
          »
          7 лет назад, # ^ |
            Проголосовать: нравится 0 Проголосовать: не нравится

          I'm not sad though :v Don't worry about that.

          It is a really nice problem. Good luck next time :)

          BTW, it'd be nice if you would add some more explanation in the editorial, like why the queries order doesn't affect the answer and how to speed up the solution using bitset.

  • »
    »
    7 лет назад, # ^ |
      Проголосовать: нравится +5 Проголосовать: не нравится

    I am really sorry for that. I tried to hack "Best Mask" with brute force and some greedy, but managed to get at most 75% points with tons of optimizations. I can give a code a bit later, because hackerrank is not available now.

    As for "Road Trip" I didn't try to submit any solution, because I couldn't find normal solution even assuming, that tests are random. Seems like there are many queries with equal xi in the testset :(

    • »
      »
      »
      7 лет назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится

      That's the reason of my sadness being on the opposite side... I'm relatively at the top of the leaderboard not because of my solving skills but because I assumed there could be weak tests -_-

  • »
    »
    7 лет назад, # ^ |
      Проголосовать: нравится +10 Проголосовать: не нравится

    Usually last task on Codesprint (especially on data structures) has binary scoring system. I wonder why didn't they do it this time.

    • »
      »
      »
      7 лет назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится

      Last time they did and I wondered why they did it :'( . I am not against strong cases, but I do not like binary scoring, so many equal scores last time.

  • »
    »
    7 лет назад, # ^ |
      Проголосовать: нравится +10 Проголосовать: не нравится

    In city construction , I did meet in middle bfs. Started bfs from one node amd another bfs from other node but in reverse direction(maintaining reverse graph). If both bfs meet in middle then path exist else not. PAssed all test in jAVA

»
7 лет назад, # |
  Проголосовать: нравится +10 Проголосовать: не нравится

Let me share solution on problem E.

Let's sort all possible 226 masks and all ai by its popcnt(num of ones). After that we gonna use binary search of popcnt.

For fixed p = popcnt we check every mask in the straightforward way (remember we have sorted ai?).

Also we even could optimize and check only those ai with popcnt(ai) < 27 - p (because of Dirichlet principle).

Any similar solutions?:)

  • »
    »
    7 лет назад, # ^ |
      Проголосовать: нравится +5 Проголосовать: не нравится

    What is the straightforward way?

    • »
      »
      »
      7 лет назад, # ^ |
        Проголосовать: нравится +5 Проголосовать: не нравится

      just check if current mask suits every ai. We stop checking current mask if we meet such ai that ai&mask = 0.

      Because of sorting order (by popcnt) we wouldn't perform too much operations.

  • »
    »
    7 лет назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится

    I do! It works under 0.6s in all testcases.

    Code

    By the way, I wonder if this method is actually correct. Can anyone prove its correctness or give a counterexample?

    • »
      »
      »
      7 лет назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится
      int n = 100 * 1000;
      for(int i=1; i<=n - 50; ++i) cout << 3;
      for(int i=2; i<=26; ++i) cout << (1 << i);
      

      try this one

      • »
        »
        »
        »
        7 лет назад, # ^ |
          Проголосовать: нравится 0 Проголосовать: не нравится

        We could remove duplicates without any regrets;)

        • »
          »
          »
          »
          »
          7 лет назад, # ^ |
          Rev. 2   Проголосовать: нравится +20 Проголосовать: не нравится

          Ok, try this one:

                  int M = (1 << 18);
          	vector<int> a;
          	for(int i=1;i<M;++i){
          		if(popcnt(i) <= 7 && i % 2 == 1){
          			a.push_back(i);
          			if(a.size() == 99999) break;
          		}
          	}
          	int c = 0;
          	for(int i=18;i<=25;++i){
          		c ^= (1 << i);
          	}
          	a.push_back(c);
          	printf("%d\n",a.size());
          	for(int i=0;i<a.size();++i) printf("%d ",a[i]);
          

          UPD: It could be even worse. I just post this one because it can be launched on codeforces in custom invocation.

    • »
      »
      »
      7 лет назад, # ^ |
      Rev. 2   Проголосовать: нравится 0 Проголосовать: не нравится

      I think the worst case might be: all a[i] have the same popcount k; the last a[n-1] is 1..10..0, and the rest of them will have ones in the last 26-k bits. So, all masks under (1<<(26-k)) will fail for the last a[i].

      Runtime will be at least ((1<<(26-k))-1)*N, where N is the expected number of comparisons before failure for each mask<(1<<(26-k) ). If this will run in time for all k between 5 and 13, I think the solution is good.

      • »
        »
        »
        »
        7 лет назад, # ^ |
          Проголосовать: нравится 0 Проголосовать: не нравится

        Make a[i] odd for 0<=i<n-1, a[n-1] = 1..10..0. Then (1<<(26-k-1)) odd masks will run through all min(10^5-1, choose(k-1, 26-k-1)) numbers.

»
7 лет назад, # |
  Проголосовать: нравится +3 Проголосовать: не нравится

In problem "The Best Mask", i was trying an approach similar to a problem (let's call it Rooks in a Chessboad) that ask to put the max number of non-attacking rooks in a chessboard with prohibited cells, that uses bipartite matching between rows and columns (it's a well konw problem in bpm). The things is I could't find such solution in the end, so it's possible to solve this problem using this approach ??? anybody has a similar solution and can explain it. Greetings

»
7 лет назад, # |
  Проголосовать: нравится +10 Проголосовать: не нравится

Did anyone understand the editorial solution of THE best mask ??

https://www.hackerrank.com/contests/world-codesprint-11/challenges/best-mask/editorial

»
7 лет назад, # |
  Проголосовать: нравится +13 Проголосовать: не нравится

Anyone received the prizes? 3 month is quite long to wait..