Common BoardBe careful, the input numbers are float, though sample and all tests here have only integer numbers. It appears first at <= 6th test. wa4 have test n=1 and some m if u use dp and u write in your massive some int, when u write, u delete int and create new ints. But if u have n=1, u now answer for every for n=1 and when u use dp its write 0, it enters zero instead of the answer you wrote down, although there should be one in some cells
Just curious did anyone managed to pass the time limit using binary search + rolling hash or the test data are specially designed to be solved in time only by an efficient suffix tree/array implementation? I tried an O(N.log N) suffix array (although finding the length of a match was O(N.log N.log N)) and it was too slow, although it ran in about 1.3s on my machine. Test 10 was very hard for binary+hash solutions,but double or triple hash would pass it. These solutions are correct, because the test set was really hard. The solutions of the authors are based on suffix trees (Nikita Rybak, Pascal) and suffix arrays (Ilya Grebnov, Java) and pass the TL easily. Thank you Dmitry! It seems that pretty soon Ukkonen and/or efficient suffix array implementations will become a must in real time contests. I would like to congratulate the autors for the excellent problem set! Single hash-based solution got AC too I got AC with optimized single hash-based solution too. But if I wrote double hash based solution I wouldn't have +9. I got TLE on #28, with single hash solution. The simplest solution with single hash gets AC in 0.468 Some statistics: 0. Suffix Automaton get AC in C++ 0.125 time and 22 320 KB Memory, author is [SPbSU ITMO] WiNGeR 1. Suffix Automaton get AC in C++ 0.14c with 22220КБ Memory, author is Burunduk1 3. Suffix Tree gets AC in 0.14 time and 23 888 KB Memory, author is [SPbSU ITMO] WiNGeR 4. Suffix Array with O(N) implementation get AC in C++ 0.343c with 5756 КБ Memory, author is me 5. Single Hash get AC in C++ 0.39c with 4024 КБ Memory, author is me 6. Single Hash get AC in Pascal 0.5c with 6191 КБ Memory, author is me 7. Suffix Tree get AC in Pascal 0.656c with 16416 КБ Memory, author is Kit(Vologda SPU) 8. Suffix Array with O(NLogN) implementation get AC in C++ 0.765c with 2756КБ Memory, author is me 9. Suffix Array with O(NLogN) implementation get AC in Java 1.406c with 5503КБ Memory, author is me Edited by author 22.12.2006 15:35 Edited by author 25.12.2006 11:24 Edited by author 11.02.2007 13:44 Edited by author 11.02.2007 13:45 Edited by author 11.02.2007 13:45 I write Suffix Tree(Ukkonen Algorithm). AC - 1 sec. But I used 30mb memory. I tried to solve this problem using Suffix Tree (ukkonen95) and got MLE on test #9, what trick did you use to reduce the memory? Then I saw this discussion about Suffix Array, I tried Larsson-Sadakane algorithm and got WA on test #8. Then I tried Karkkainen-Sanders algorithm and got TLE on test #9. I haven't try to use Suffix Automaton yet. This problem is really hard. Anyone can give hints about reducing memory for the Suffix Tree? I tried to solve this problem using Suffix Tree (ukkonen95) and got MLE on test #9, what trick did you use to reduce the memory? No tricks, I have almost double reserve in memory. But I use hash working with edges, may be that's the matter. Test #8 is extremally small, so you can find similiar manually. #9 is just the first large test. Good luck! No tricks, I have almost double reserve in memory. But I use hash working with edges, may be that's the matter. Yes, I got it Accepted at last :) The trick is to use your own hash implementation rather than hash_map from STL! Did anybody solve this problem using STL? I just got AC with Suffix Array + LCP in 0.3xx secs. The implementation is cleaner than Suffix Tree and requires less space yet still run in O( N ) time. I'm curious with Burunduk1's Suffix Automaton, is there any online resources available to learn about Suffix Automaton? I really want to solve this problem using Suffix Automaton :) >This problem is really hard. Anyone can give hints about >reducing memory for the Suffix Tree? I also had MLE#9, after that I saved at node of suffix tree only used links to child And got AC. It reduced memory, but I my prog eat 30mb. Those who solved it using Suffix Trees: Did you built 2 Suffix Trees or just 1? What I did is to create 1 Suffix Tree with string: s1 + "$" + s2 + "#" where s1 and s2 is the first and second string in the input. After I built the Suffix Tree, I traversed it and find the deepest node which has child "$" and "#". Or is it better to create 2 Suffix Trees and compare the two trees? Or there is a way to build a Suffix Tree only for the first string and try to find the LCS with the second string using that Tree. Did you get AC using the first algorithm? second? or the last? Thanks I use hashing but my algorithm is O(n(logn)^2), is it a better way? Here is my algorithm: m = the result l = length(m) - Do a binary search on l Check whether there is a common substring length l: + Calculate and sort hash values of string 1 (into array f) + For each value in string 2, search it in f, check whether there is a match! What is double hash??? My single hash O(N*logN) prog. got AC within 0.671 sec. and 6,... MB memory. What I did is to create 1 Suffix Tree with string: s1 + "$" + s2 + "#" where s1 and s2 is the first and second string in the input. After I built the Suffix Tree, I traversed it and find the deepest node which has child "$" and "#". this is exactly what iam trying to do but i got stack overflow in test case 9, obviously the stach overflows when i traverse the tree wishing to find the deepest node which has the two terminator characters as children (or in the subtree below). I guess the tree is too deep, so how could u solve this part? Don't traverse the tree using recursion ;) Try using explicit array[100000] Don't traverse the tree using recursion ;) Try using explicit array[100000] Do u mean to use that array to bottom up traverse the tree? or u mean something else? Don't traverse the tree using recursion ;) Try using explicit array[100000] Do u mean to use that array to bottom up traverse the tree? or u mean something else? A recursion is using stack implicitly (stack memory) and it has limitation on the depth of the recursion for some compiler (or maybe by the stack memory configuration of the compiler). So, instead of using stack memory we can use an explicit stack array to simulate the same behavior. However, the code gets uglier and harder to read :p Suffix Tree gets AC in 0.14 time and 23 888 KB Suffix Automation gets AC in 0.125 time and 22 320 KB autor is me P.S. Who can tell me, how to implement Suffix Array in O(n)? Suffix array can be constructed in O(n) time by Karkkainen-Sanders algorithm. Hi WiNGeR, You might be interested to see this demo about creating Suffix Array in linear time by Juha Karkkainen and Peter Sanders: http://felix-halim.net/pg/suffix-array/index.php Do you have any reference on how to build Suffix Automaton? Which one is simpler? Suffix Tree or Automaton? Thanks i relalize double hashing, but i get tle on test 9. Can anybody get me hash-functions used in solution on this problem? try 64bit hashing I can't use single hash to solve the problem... Would you please tell me how to design the hash? And what is the 64bit hashing meaning? As far as I am concerned, Suffix Automata are the best tool for solving this problem. At least, it holds for me. I got AC three hours after I started reading "Automata for Matching Patterns" ( http://www-igm.univ-mlv.fr/~mac/REC/B4.html ). Earlier I spent much more time on Suffix Trees and Arrays - and I failed to solve this problem by their means. Would be grateful for any hints concerning Trees and Arrays (just curious). I used the standard ukkonen implementation. However, I use sibling lists for edges representation (watch Wikipedia "Suffix tree"), and I make leaves of tree explicit, that means that in the worst case you have 2*N nodes totally, N of them are leaves, where N is the total size of the text. This works fine. Also, for the traversal of the tree, I used simple recursion. I tried to use stack modelling, as someone proposed in the posts earlier, but failed with TLE on test 9. In order not to get stack overflow set up the size of the stack about 10 megabytes (watch FAQ in order to learn, how to do it). I just did it with hash and my own hash table for 0.265 sec and 7mb memory. I used the standard ukkonen implementation. However, I use sibling lists for edges representation (watch Wikipedia "Suffix tree"), and I make leaves of tree explicit, that means that in the worst case you have 2*N nodes totally, N of them are leaves, where N is the total size of the text. This works fine. Also, for the traversal of the tree, I used simple recursion. I tried to use stack modelling, as someone proposed in the posts earlier, but failed with TLE on test 9. In order not to get stack overflow set up the size of the stack about 10 megabytes (watch FAQ in order to learn, how to do it). Totaly agree. Sibling lists save memory well, and work pretty fast. I also needed to increase stack size. http://acm.timus.ru/status.aspx?author=48362&from=3761647&count=1 Edited by author 27.10.2011 02:46 Edited by author 27.10.2011 02:46 Hi! I have tried so many interpretations of the main idea for finding suffix array in O(NlogN), but all of them (except 1, because I optimize it) ran for more than 2 second . Would you share the secret, I mean is there something special you do? There is no any secret. Try to find original article "Faster Suffix sorting" by N.Jasper Larson and Kunihico Sadakane. Also very useful article for this problem is "Two Space Saving Tricks for Linear Time LCP array Computation" by Giovanni Manzini. Just got 0.96s and 28M memory with suffix automaton. How do i make it fast? String hashes + binary search: 0.468 s String hashes + hashset: 0.234 s Suffix automation AC C++ MSV2013 0.093 sec 22 MB, yeah Actually, not any hash is suitable here. Why not suffix automaton? It is much easier to implement and, of course, gets AC =) please answer to me. 6 years have passed. But anyway, maybe this will help someone, the test number 3 is N = 1 5 years passed. anyway thanks. I has helped me. :) #include<iostream> #include<cmath> #include<cstring> long long int n; int main(){ const int k = 256; std::string g = "GOOD"; std::string b = "BAD"; std::string str; std::cin>>str; std::cin>>n; if( n == 0){ std::cout<<"0"<<"\n"; return 0; } int arr2[4]; int bit = 1; int arr[4]; long long int l = 0; memset(arr,0,sizeof(arr)); memset(arr2,0,sizeof(arr2)); for(int i = 3;i >=0 ; i--){ long long int j = pow(k,i); for(int C = 1;C<=255;C++){ long long int h = C*j; if( n >= h){ l = n % h; if(l==0 && i!=0){ arr[i] = 1; bit = 1; n = n-bit*h; break; } else if( i == 0 && n <255){ arr[i] = n; break; } else { arr[i] = n/h; bit = n/h; n = n-bit*h; break; }
} else break; } } if(str == g){ long long sum = 0; for(int i = 0,m = 3; i<=3,m>=0;i++,m--){ sum+=pow(k,m)*arr[i]; } std::cout<<sum<<"\n"; } else if( str == b){ long long int sum = 0; for(int i = 0,m = 3; i<=3,m >= 0;i++,m--) sum+=pow(k,m)*arr[i]; std::cout<<sum<<"\n"; } else; return 0; } dude, 14 lines is enough to solve this problem if u have wa 44 just remove one in the cyclic factorization, if there is one. <=sqrt() + 1 -- bad <=sqrt() -- good Can anybody help? Easy solution without optimization efforts. Use Matrix A= [0 1 0 0 0 0] [0 0 1 0 0 0] [0 0 0 0 1 0] [0 0 0 0 0 1] [c1 c2 c3 c4 c5 c6] Answer=[[A^(X-N)]*K][N] Thus we must calculate pow A^(X-N) Use famous O(lg) pow in groop of matrix __int64 in inner calculations and int (rez)%Y as result My such solution ran for 2.9 seconds with 3 for TL. So it's still not enogh for stable solution. I had to differentiate between M^2 and M*A matrix multiplications (the latter can be implemeted via int, +, - and >=), then it ran for 1.5 sec :) My such realisation works in 0.609. This time even without optimizations on +- for fast modulus, and not using fact that matrix is sparse in those cases (so multiplication can be done at O(N^2)) - it's 0.078 sec. With these optimizations - 0.046 sec. Edited by author 17.08.2022 11:56 This was overall a great problems set! Can anyone give a hint on the solution for "J. Turning Turtles"? What special property (beside that it's a tree) must one use? What is the complexity of the intended solution? Thanks in advance! This problem can be solved in O(N + Q*logN), where N is the size of the field. Am I right that we build slightly another tree and then use LCA on that? =) And when the problems will be added to the problemset? Actually it is possible to use the given tree. But calculating the answer is not very trivial. I was glad to use successfully LCA with forgotten implementation. It is enough to know what LCA do. It is mean that LCA very adequate tool for tree and cannot be omitted in learning. It is possible to use given tree, but my complexity is O(N*log(N)+Q*log(N)) - 0.25 sec and quite a bunch of RAM. For every node store its 1st, 2nd, 4th, 8th, 16th, ... 2^16th parent. Also store number of turns on that path and final orientation after last move (horizontal/vertical). This information is enough to calculate answers at log(N). 1. Use integer calculation for judging if the answer is -1 or 0. 2. Use integer calculation until the last step for the area (an integer-division). 3. Use 'long long' instead of 'long' or 'int'. Also, here are some cases which might help. 0 0 -1000 0 0 0 1000 1 1000001000.000000 -1000 0 0 1000 0 -1000 1000 -999 2002004004.004004 0 400 1000 1000 -1000 -1000 355 -187 -1 0 400 1000 1000 -1000 -1000 350 -190 0 0 400 1000 1000 -1000 -1000 353 -188 16931680400.000000 -1000 -1000 1000 1000 -1000 -1000 1000 999 31984004000.000000 -1000 -1000 1000 1000 -472 -851 379 1 5800420000.000000 More tricky cases: 0 0 3 0 1 0 1 0 0 The following testcase helps me to beat WA#33. 0 0 3 0 0 1 3 1 -1 Edited by author 27.11.2012 17:54 Edited by author 27.11.2012 17:54 Edited by author 27.11.2012 17:54 This test shouldn't be applied: 0 0 3 0 1 0 1 0 0 because it is said that window lengths are positive. And that's true, I've checked. Or maybe a misprint? -1000 0 0 1000 0 -1000 1000 -999 2002004004.004004 i get 2002004.0040040, but accepted. Same here, also another test is incorrect. All others are fine. -1000 0 0 1000 0 -1000 1000 -999 2002004.00400400 0 400 1000 1000 -1000 -1000 353 -188 16931680400.00000000 Since input numbers are integers, pseudovector product absolute value will be at least 1 if they aren't parallel, so you can compare it to 0.5 to have bigger margin for double precision error. Just get cross-product (dx1*dy2-dx2*dy1). If it's zero - they are parallel. When n>10 is a prime, i am writing n=k*3+l*2, where l=1,2 or 3 depending whether n mod 3 = 1 2 or 0. Then I get lcm=3^k*2^l, which is the maximal with respect to all possible divisions of n. However, my program gives WA6. Am I correct? Thanks! Clearly the lcm of k 3's and l 2's is at most 6 -- you are asked the lcm of them, not the product of them. Head-on solution have complexity O(2^40)=O(10^12). It's very slow. How do it faster? I used 40=30+20 First 20- memorization second 20 as 2^20=10000000- that normaly Could you explain your solution more in detail? "First 20- memorization" What it mean in Russian? I understood that what we do with second 20. But can not understood that what we do with first 20. =) I meant that first 20 also as 2^20 or with brute force aproach, but result of first 20 we place in arr[1..1000000](memorization) sort arr than in second 20 use log-bin search in arr. Thank you very much. You is good man! I got AC. =) It's a bit more complicated than that because you should care about rod not getting off the rails during the process as well, so you can't just pick arbitrary memorized sequence which gives suitable end-result, it also must stay within limits while it performs memorized shiftings. Looks like segment tree algo, not just plain binary search (or tests are very weak). P.S: Got AC with 0.5 sec and 44Mb, probably could've done better. For every 2^20 endings I track range of start values where it is suitable (i.e. fits for its entire internal history), then for every 2^20 beginnings (sorted) I track min/max of currently active segments via two heaps. Edited by author 16.08.2022 11:51 P.P.S: Ah, I'm dumb! Memorizing first 20 leads to much easier algo when last 20 are brute-forced (not vice versa). 0.265 sec, 7 Mb. Yet, coding that monster from previous "P.S" was fun :) Why is the correct answer in the example "uhhdud" and not "uhdudh"? in terms of lexicographic order, this combination is closer to the original data. It's not next in the book, it's before. d < h < u Let a[1], ... , a[n] be the sequence written by the friend and pref[i] be the xor of the prefix a[1...i]. Then a question (l, r, t) (which means the parity of the number of ones on the segment from l to r is t) can be represented as (pref[r] xor pref[l - 1] = t). Let's build a graph with two vertices for each prefix (thus, there will be 2 * (n + 1) vertices). Using compression, we actually need only at most 2 * m vertices (where m is the number of questions). Let the vertices corresponding to the prefix i be f0(i) and f1(i). Now, let's add all edges f0(i) ~ f1(i). For a question (pref[r] xor pref[l - 1] = t) if t = 1, we add two edges f0(l - 1) ~ f0(r) and f1(l - 1) ~ f1(r), else if t = 0, we add edges f0(l - 1) ~ f1(r) and f1(l - 1) ~ f0(r). To check whether a sequence of questions from 1 to x is achievable we just need to check whether our current graph is bipartite. This can be done by simply doing dfs after each question. Nice! Can you please elaborate in a few words? I actually didn't get the significance of having two vertices for each prefix and how it's solving the problem. Though O(N*log(N)) and O(N) both gave me 0.068 timing, it's a good testdata to write such code, would matter if N could be up to 10^6. Also this solution with O(1) stepping may additionally report number of ways to achieve minimal result. The structure is doubly-linked list of available amounts (always strictly ascending), each of which is non-empty doubly-linked list of characters with that amount. This structure allows to query for max and to change amount of single character +-1 at O(1). Could anyone who solved it share the idea? My solution was: iterate over all vertices i. Fix each i start bfs, so you get a tree (rooted in i). Find it's diameter (from the farthest node v from root i start another BFS and find the farthest node u from v. The distance from u to v would be the diameter). Across all the diameters find the minimum, that would be the answer. This solution got WA 8. After random_shuffle() on adjacency lists I've got WA 17. Now repeat this solution 100 times and you get AC. So my question is, what is the solution? 1. Find shortest paths from all vertices with Floyd-Warshall or BFSes 2. Brute force all possible tree centers. Note, that a diameter center can be either a vertex or an edge. Basically, my solution is exactly yours while I believe you've forgotten to check edges that can form a center. My solution is completely deterministic. Edited by author 07.11.2018 17:03 Edited by author 07.11.2018 17:03 I just tried all vertices and all edges (meaning pushing both neighbors in priority before BFS starts), then checked tree diameter across all vertices, not just to these roots (there is O(N) algo for that). I used no Floyd-Warshall for candidates, just tried all pairs v1 <= v2, besides I am not sure Floyd will help here because original graph diameter can be shorter than that of resulting tree (e.g. see WA17 topic). Use this test 6 9 5 6 3 4 2 4 1 5 3 6 1 2 1 6 4 5 Thanks, helped me to get AC, but first line in your test should be 6 8. Correct answer is diameter 3. att Graph is not oriented. Word "direct connection" in the statement means connection w/o intermediate nodes. hi, im trying to solve this problem and would like to get tips in the right direction of solving this problem. would a grapha matching solution work? or perhaps a minimum cost flow solution? or anything else? thanks in advance. My solution is to find really optimal matching with min-cost max-flow. Then compare it to one from input. I solved it with negative cycle searching. My algo have following complexity: (N+M)*(2*N*M + M*M) It can also be a chain ending up in shelter with residue capacity. It is also possible to make it N*M*M + M*M*M by jumping from shelter to shelter through one preselected building which grants maximum yield for that pair of shelters (hence the first N*M*M step), M*M*M is Bellman-Ford. |
|