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

Автор vovuh, история, 9 лет назад, По-русски
Tutorial is loading...
Tutorial is loading...
Tutorial is loading...
Tutorial is loading...
Tutorial is loading...
Tutorial is loading...
Tutorial is loading...
  • Проголосовать: нравится
  • +59
  • Проголосовать: не нравится

»
9 лет назад, скрыть # |
← Rev. 2  
Проголосовать: нравится 0 Проголосовать: не нравится

I have tried Problem C. First I found all cycles and then I found In how many cycles a edge is present. Then If there is any edge which appear in all the cycles (edgescount==cycles) Then answer is Yes otherwise No.

But I am not able to find all cycles correctly. Can anyone suggest How I can find all cycles in a Directed graph.

Link to my solution http://codeforces.me/contest/915/submission/34176793

  • »
    »
    9 лет назад, скрыть # ^ |
    ← Rev. 2  
    Проголосовать: нравится +1 Проголосовать: не нравится

    You don't need to find all cycles, just one.

    If other cycles in this graph share an edge with this cycle you found, then by removing this edge you break the other cycles and make the graph acyclic. If there are cycles which don't share an edge with the cycle you found, then you of course can't make the graph acyclic by removing just a single edge from the graph.

    Therefore it suffices to find just one cycle, as the editorial says.

    Also I guess that there can be a lot of cycles in a directed graph, maybe too many to store.

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

I did C with simply dfs. I guess it has complexity O(len!), where len is the length of 'a' and '!' is factorial. It passed all the system tests, but I'm not sure that it's correct. 34181569

  • »
    »
    9 лет назад, скрыть # ^ |
    ← Rev. 3  
    Проголосовать: нравится +3 Проголосовать: не нравится

    It seems it's about O(2len).

    On each step you either put the digit that is present in this position in b or the greatest digit smaller than it. Like the first possibility lead to the same brute with len - 1 and the other one ends instantly.

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

      Your explanation is't clear for me. I do the cycle from '9' to '0' on each step ( we can consider that we have number = 999.... I can't see there 2^n. Can you explain it more detailed? Maybe on some test. I'm still thinking that it will work for the len 10^3 and more.

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

        You iterate over all digits but only 2 of them will be considered at maximum. It could have been O(10len) instead of O(2len). In worst case you will check bpos with can = false, fail and then proceed to the next present digit (you will get answer in no time).

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

    I solve it with dfs, too. As a matter of fact, I prefer to considering its complexitiy O(|A|len). 'Cause we have greedy algorithm. First, we choose the maximun digit (also not greater than b1) for a1 and do it again and again. For example, if a1 < b1,we can disgard the limit of not greater than b1, and then whatever remains, we just choose the maximun digit. But if a1 = b1, we just wait until ai < bi.

»
9 лет назад, скрыть # |
 
Проголосовать: нравится +5 Проголосовать: не нравится

Does anyone have a faster solution for D? I prefer not to live on the edge.

»
9 лет назад, скрыть # |
← Rev. 3  
Проголосовать: нравится +5 Проголосовать: не нравится

Need help.

My code for D passed during upsolving. And I have no idea how.

What i did:

Toposort N times (start from a different node every time, still doing a dfs for every connected component, just beginning node is different.)

for each ordering check if the number of edges that fail the relation of toposort is 1 or 0. If any such order exists, then print YES else NO.

Can any one tell me why this worked?? Or maybe the test cases are weak?? I was not expecting this to pass at all. Submission: code //sorry for super poor indent.

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

    Can you give the proof of correctness of this solution?

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

    Suppose that there is no 1 edge removal solution. Then your code will surely output NO, there is no way to topsort the edges with only 1 back edge.

    Next, suppose that there is a 1 edge removal solution, and let that edge be from node a to node b. At one point, your code will do a topological sort from node b. Consider the result of that sort. Surely we shall have the back edge from b to a, but I claim there will be no others. Suppose a,b,c,d are distinct nodes. If there is a back edge from d to c, then there must be a path from c to d as well (because of how topological sort works). But then this cycle does not use the edge a->b at all, so removing the ab edge will leave a cycle, contradicting our earlier claim.

    When your code does the topological sort from b, then, it will find a valid solution and print YES. Hence it is correct.

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

In Problem E, how is the time complexity O(q * logq)? After finding the first interval that intersects with the query, one needs to go over all the following intervals that intersect the query. That should amount to for query i, and hence, O(q2) overall. However, this passes system tests 34180929. What am I missing?

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

    In each query you will add no more than 1 segment (size of set won't exceed q). And those that you touch when updating, you delete immediately, so it's q deletions at maximum.

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

Can someone explain how t(i) is made in more details?

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

    t(i) is not made explicitly in the program. it is a model that helps you think about the question. What is important is how to determine v_1, v_2, ..., v_k.

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

      UPD : Ok, I understood, but why are we adding every s_i. Let's saz we have root i, its children j and j's children p (this is some part of the tree t(i)) than s_j is 2 and s_p is 1, then we have s_j + s_p choices (based on first summation) which is 3 but we have 2 choices? What am I missing?

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

        So, the idea is that t(i) is the sub-tree that contains the paths and that v_i will be the maxima on all paths of that tree. (otherwise, the given formulae will not hold).

        That said, in t(i), v_j is connected to v_i directly if (v_i, v_j) is in the original tree and a_j < a_i. Likewise, v_j is connected to v_i indirectly if (v_j, v_k) is in the original tree and v_k is connected to v_i directly or indirectly.

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

can anyone accept F with centroid ?

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

could anyone accept F with centroid ?

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

Можете прояснить два момента:

1) После завершения открытых взломов проводится ли какая-то полная проверка всех решений? Или неправильные решения, не замеченные взломщиками, так и остаются "правильными"?

2) Когда планируется обновление рейтинга для div2?

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

Can someone explain the segment tree solution to problem E?

»
9 лет назад, скрыть # |
← Rev. 2  
Проголосовать: нравится 0 Проголосовать: не нравится

Can anyone explain solution for problem E in detail? Thanks!

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

    Problem E is a simple data structure. What you need to do is to build a Segment Tree. The lenth of it is n(that is, equal to 1e9), but do not build the whole Tree. Only if you want to get some information from the interval, you make it. In a word, that is a dynamic-building Segment Tree.(I don't know what its exact name in English)

  • »
    »
    9 лет назад, скрыть # ^ |
    ← Rev. 7  
    Проголосовать: нравится +17 Проголосовать: не нравится

    My solution (the same as author's):

    0) Let's create set < pair < int, int >  > , where we will store all non-working days as {Ri, Li}. The main rule is that segments should not intersect — then we can merge existing segments with new (or cut segment).

    ans = n

    1) K = 1, we should add segment [L;R] in our set. Let's find all segments where Ri ≥ L (it means that new segment and these can have intersection). We can find first such segment by lowerbound({L;0}) (remember that set sorted by Ri). While Li ≤ R we should continue iterating over set, on each iterate we are merging segments:

    -make L = min(L, Li), R = max(R, Ri)

    -erase segment {Ri, Li} from set — now it is contained in our [L;R] segment.

    -ans = ans + (Ri - Li + 1) — formally we erased segment and made days [Li;Ri] working (but we will change it later).

    When we archieved Li > R or end of the set, we make:

    -insert our merged segment {R, L} in set

    -ans = ans - (R - L + 1)

    -print ans

    Example: we had set = ({1, 1}, {5, 2}, {10, 7}, {13, 12}) adding segment with L = 4, R = 9

    lowerbound({4, 0}) will find us first pair {5, 2}, 2 ≤ 9:

    L = min(4, 2) = 2, R = max(9, 5) = 9

    then pair {10, 7}, 7 ≤ 9:

    L = min(2, 7) = 2, R = max(9, 10) = 10

    then pair {13, 12}, 12 > 10, stopping and inserting resulting segment {2, 10}.

    resulting set = ({1, 1}, {10, 2}, {13, 12})

    2) K = 2, similar with previous one, but we are cutting stored segments (and insert them back at once) and do not insert something at the end.

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

Has anyone solved Problem D using approach which is given in editorial by first finding one cycle

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

How to solve E using segment tree?

  • »
    »
    9 лет назад, скрыть # ^ |
    ← Rev. 5  
    Проголосовать: нравится +10 Проголосовать: не нравится

    The idea is the following. We simply create an array of size n. array[i] = 1, if i is a working day, and array[i] if not. For each query L R k I update all elements between array[L] and array[R]. The sum of all elements is the answer.

    But doing a range assignment / computing the sum takes O(n) time. Way too slow.

    Since this are range assignments and range sums, the solution is obvious: lazy segment tree. This will give O(log n) per operations. Much better.

    But a lazy segment tree will take O(n) memory. That is too much, since n is really big.

    There are two approaches to fix this.

    1) The first one is to compress the indices. (This means, if there are only the three queries 1 100 1, 50 150 1, 20 80 2, then the elements 1, 2, ..., 49 don't actually need to be represented by 49 single nodes. We can combine them, since they always have the same value. Similar with the other intervals. I.e. we can create an compressed array that represents the segments [1-19], [20-49], [50-80], [81-100], [101-150]. The first element will switch between 19 and 0 (depending it all elements in that interval are working days or not), the second one between 30 and 0, ... depending if the complete segment consists of working days or not.

    2) The second approach is to make a dynamic segment tree. The idea is this: since q is not really big, we will only visit a small part of the tree. Most nodes in the segment tree will never be visited. So we can save quite a bit of memory (and time), if we only create the segments that we really need. We start with only one node [1-1e9]. If we need to go to the children, we simply create them on the fly. I.e. if we want to visit them, we simply create two nodes [1 — 5e8] and [5e8+1 — 1e9]. And if we have to go deeper on the left side, then we create more nodes there. Since one range query only visits O(log n) nodes, we have a total memory and time complexity of O(q * log n). In the implementation each segment will have to pointers pointing to the left and the right child, and which are possible null.

    You can check out my implementation: 34199755

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

    I used coordinate compression with normal segment tree with lazy propagation. Very easy solution. https://codeforces.me/contest/915/submission/83613121

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

How can I make this solution to pass? It applies the same idea as described in the editorial: 34202909

»
9 лет назад, скрыть # |
← Rev. 2  
Проголосовать: нравится 0 Проголосовать: не нравится

[del]

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

Конечно, идея банальная, но может в разборе также прикреплять исходный код с реализацией решения и объяснением каждого действия? Я считаю это было очень полезно, кто со мной согласен?

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

Can someone please explain F and G in more detail?

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

In problem E, can someone tell what optimizations I can make? http://codeforces.me/contest/915/submission/34222959

I did the same as the editorial explained.

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

I notice that there's a "flows" tag in 915G (Problem G). Can anyone explain how this problem can be down using flows?

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

how to do question 915C using bfs? Can somebody explain!!

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

I wonder how to find divisors for every numbers in [1,k].
I use a preprocessing to find every multiple for numbers in [1,k],which is O(k log k),and store the divisors in std::vector but got a MLE.
At last I have to set a constant S=5e5 and find divisors with O(sqrt(i)) brute force when i<=S,and store the divisors when i>S.It got Ac,but it's really strange.The editorial didn't mention the way to find divisors,so how can we deal with MLE?

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

In problem D, I assumed if we destroy a node from this graph and can not find a cycle then the desired edge should be connected with that node(from and to). I took one node that meets that condition. So, now It is just needed to destroy at most (n+n) edges. So, total complexity is O(n(n+m)).

But the assumption is wrong, any node that meets that condition does not necessarily have the desired edge connected with it. So, I took all nodes that meet that condition and checked randomly from each node till I get a desired edge. This one passed in less than half second. Total complexity is O(k*n*(n+m)) where k is number of such possible node. But I think in practical this k should be very small. I can not come up with any graph to disprove this and I am not also sure if the k should always be very small.

»
8 лет назад, скрыть # |
← Rev. 8  
Проголосовать: нравится 0 Проголосовать: не нравится

.

»
8 лет назад, скрыть # |
 
Проголосовать: нравится -8 Проголосовать: не нравится

I think there is a mistake in problem c's statement

first it says "not exceeding b" then it says "not greater than b" :\

I hope you fix it.

»
8 лет назад, скрыть # |
← Rev. 2  
Проголосовать: нравится 0 Проголосовать: не нравится

In problem G: we can prove that the number of arrays with gcd = 1 is the sum of the following values over all possible sets S ...

Can someone please provide some hint or link to the proof?

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

KEK

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

I solved problem C by using greedy. It's quite hard for me to implement this solution. But I am training DP, and this problem was tag DP. Could you give me hint to solve this problem using DP or It is just wrong tag.

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

Problem D can be solved in O(n + m). Let's build SCC (strong connectivity components). Now let's notice that if we have more than 1 SCC, then the answer is NO. Otherwise, if our SCC has the number of edges equal to the number of vertices, then the answer is YES (sorry, there is not full idea)

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

I solved C using recursion, the idea is same as the editorial. Submission

»
3 года назад, скрыть # |
← Rev. 4  
Проголосовать: нравится +1 Проголосовать: не нравится

I have some problems about E. I implemented a dynamic segment tree with pointers and got TLE、MLE. So I use fake pointers instead of pointers, however it got WA. Then I changed some details (I let auto &a = seg[id] and operate on a in the second version. I changed all the a to seg[id] in the third version.) and got AC.

I'm very curious about why my second version of code got WA. Can anyone tell me why.

Here are my three submissions : 244770506 244771884 244772256

Sorry for my poor English and I really appreciate your help.