-1

Problem Link: https://cses.fi/problemset/task/1091/

I am assuming there is some kind of issue relating to time complexity but I am unable to identify what I am doing wrong here.

Getting Time Limit Exceeded verdict in this code:

#include<bits/stdc++.h>
using namespace std;
#define int long long int
main()
{
    int n,m;
    scanf("%lld %lld",&n,&m);
    vector<int>tickets;
    for(int i=0; i<n; i++)
    {
        int x;
        scanf("%lld",&x);
        tickets.push_back(x);
    }
    sort(tickets.begin(),tickets.end());
    for(int i=0; i<m; i++)
    {
        int x;
        scanf("%lld",&x);
        auto index=lower_bound(tickets.begin(),tickets.end(),x);
        if(index==tickets.begin() and (*index>x or index==tickets.end()))
            printf("-1\n");
        else
        {
            if(*index!=x)
                index--;
            printf("%lld\n",*index);
            tickets.erase(index);
        }
    }
}

Getting Accepted verdict in this code:

#include<bits/stdc++.h>
using namespace std;
#define int long long int
main()
{
    int n,m;
    scanf("%lld %lld",&n,&m);
    multiset<int>tickets;
    for(int i=0; i<n; i++)
    {
        int x;
        scanf("%lld",&x);
        tickets.insert(x);
    }
    for(int i=0; i<m; i++)
    {
        int x;
        scanf("%lld",&x);
        auto index=tickets.lower_bound(x);
        if(index==tickets.begin() and (*index>x or index==tickets.end()))
            printf("-1\n");
        else
        {
            if(*index!=x)
                index--;
            printf("%lld\n",*index);
            tickets.erase(index);
        }
    }
}

Not understanding why is this happening.

  • the fact that you are sorting the vector before evaluation can be a reason for increased running time of the program. – Arsenic Apr 02 '21 at 10:59

1 Answers1

1

This is due to the tickets.erase(index) statement that you are using.

In vectors (no matter sorted or not), erase() is O(n) while for multiset erase() is O(logn) typically.

So, when you are using a vector and then using erase() in a for loop of size m, you get extra O(n) for each iteration of i and thus a total complexity of
O(nlogn (sorting) + m * (logn (lower_bound) + n (erase))) = O(m*n) which is way too much.

But for multiset, using erase() gets you extra O(logn) for each iteration resulting in total time complexity of
O(nlogn (insert into multiset) + m * (logn (lower_bound) + logn (erase)) = O((m + n)logn).

I hope it clears your doubt. Read below links for better understanding.
vector erase time complexity
multiset erase time complexity

risingStark
  • 1,153
  • 10
  • 17