Borjianamin's blog

By Borjianamin, history, 5 years ago, In English

Hi.
I want to solve a question. I know how to solve it but I want a better way to solve it. in first line number n is given and in second line, n numbers is given. We call value of i-th number as P_i. For the i-th number and j-th number, if (i - j) (P_i - P_j) < 0 is true, then there is edge between i and j in graph. (graph is undirected)
We want to find connected component of graph and print vertices in each connected component.

Input 1:
4
2 3 1 4
Output 2:
2
3 1 2 3
1 4
(output: print number of connected component, then each line, first print number of vertices in that component, then print vertices in increasing order)

Memory limit: 128MB
Time limit: 1 second
1 <= n <= 1000000

I noticed that the property, is property for checking inversion in an array. However the nlogn approach is only for count inversions but if I want to find them, then I need linear search in merge each time and so,my algorithm is not nlogn anymore.
There is two approach for find components. one of them is DFS and other is Disjoint set how every we want to print connected component so I thick that I couldn't use Disjoint set.
because of time limit and memory limit, I didn't know a best way.
Is it possible to help me or give me a idea?
Thanks.

  • Vote: I like it
  • -2
  • Vote: I do not like it

| Write comment?
»
5 years ago, # |
  Vote: I like it 0 Vote: I do not like it

Do you have a link to the problem? I think you can solve it in a similar divide and conquer way with Disjoint set, and if you do the implementation a certain way then it will amortize to $$$O(n \log n)$$$, but it would be nice to submit to a judge to verify before I post a possibly incorrect solution.

  • »
    »
    5 years ago, # ^ |
      Vote: I like it 0 Vote: I do not like it

    I didn't try it but If I want to use disjoint set, I need a vector to keep component and when merge two sets, merge two vector too. If it is correct, I will try it. if you have better way, please comment.

    • »
      »
      »
      5 years ago, # ^ |
        Vote: I like it 0 Vote: I do not like it

      What I've done is the classic merge sort inversion algorithm, but the only difference is as follows:

      When merging the two sorted vectors, if we take an element from the right list, we know that it should have an edge to everything remaining in our left list. However, we note that it will all become one component after that, so for any future elements in our right list that we need to merge, we can just merge it with the first element in our left list at that time. Thus, the first time we take an element from the right list, we merge with everything remaining in the left list, and then for all future elements we take from the right list, we merge with the front element remaining in the left list. This should keep the $$$O(n)$$$ factor of merging two lists the same (with perhaps some negligible ackermann term), so the complexity of the whole algorithm will remain close to $$$O(n \log n)$$$.

      Code

      There is probably a much cleaner way to attack this, but I think it should work (there also could be a bug, I don't know).

      • »
        »
        »
        »
        5 years ago, # ^ |
          Vote: I like it 0 Vote: I do not like it

        Thanks so much. I do it at first without any change in inversion count. I get some time limit but most of test are passed. When I implement your idea, I passed all tests. I didn't think about your amazing tip!!! Thanks.

        • »
          »
          »
          »
          »
          5 years ago, # ^ |
            Vote: I like it 0 Vote: I do not like it

          No problem, thanks for the problem! This was a really unique problem and this insight doesn't seem to be a common one.

»
5 years ago, # |
  Vote: I like it 0 Vote: I do not like it

please provide the link to the problem...