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

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

In the problem https://www.codechef.com/problems/CHEFQUE,

submission : https://ideone.com/l2LPvy got TLE. It used comp().

However, when I didn't use comp() and just used sort( vc.begin(), vc.end() ) it got accepted. Submission link https://ideone.com/NgbwUO.

Even though both are doing same thing, why comp() is giving TLE and how can we improve on it. Please somebody guide me on this.

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

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

I think the problem is that using a function pointer for the comparison wastes a lot of time in function calls. The second version uses the comparison operator directly.

In your example, there are 281009016 calls to comp(). This takes its toll. Passing arguments by reference saves ~0.5s. Unfortunately, it seems the compiler ignores inlining the function. So, I don't see better than just avoid using comp() here.

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

Change bool comp( pair<...> pa1, pair<...> pa2 ) to bool comp( const pair<...>& pa1, const pair<...>& pa2).

Remember that in C++, passing variables to a function copies the variables each time you call it. In your case, you are passing a pair<pair<ll, int>, bool>, which uses around 24 bytes if I'm not mistaken. In essence, by just passing your pair you already did work. What more if you did it n log n times in a sort, you get an overhead factor of 24.

The thing is, you can bypass the default parameter copy by declaring it as a constant reference. Use bool comp(const TYPE& a, const TYPE& b) instead of bool comp(TYPE a, TYPE b). By doing so, instead of copying your variables everytime, you just copy its address but reference the same variable. Normally, addresses are just around 4 bytes... 20 bytes less!

The reason why the default pair sort is faster is because C++ STL implements constant referencing in all its default sorts. It's the standard.

EDIT: It seems you already tried the constant reference but it's still TLE? Why don't you try

inline bool comp(const pair<pair<ll, int>, bool>& pa1, const pair<pair<ll, int>, bool>& pa2) {
    return pa1.f.f < pa2.f.f || (pa1.f.f == pa2.f.f && pa1.f.s < pa2.f.s);
}

~~~~~