Submission #1285440

#TimeUsernameProblemLanguageResultExecution timeMemory
1285440MMihalevLongest Trip (IOI23_longesttrip)C++20
15 / 100
1071 ms460 KiB
#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<random>
#include<tuple>
#include<chrono>
#include "longesttrip.h"
using namespace std;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
//mt19937 rng(89356);
vector<int>ans;
int n;
int cntqueries=0;
bool edge(int u,int v)
{
    cntqueries++;
    return are_connected({u},{v});
}
void special(vector<int>nodes)
{
    if(!are_connected(nodes,ans))return;

    if(!edge(ans[0],ans.back()))
    {
        vector<int>nans;
        for(int x:nodes)nans.push_back(x);
        for(int i=0;i<ans.size();i++)
        {
            nans.push_back(ans[i]);
        }
        ans=nans;
        return;
    }

    int l=0,r=nodes.size()-1;
    int pnodes,pans;
    while(l<r)
    {
        int mid=(l+r)/2;
        vector<int>tmp;
        for(int i=l;i<=mid;i++)
        {
            tmp.push_back(nodes[i]);
        }
        if(are_connected(tmp,ans))
        {
            r=mid;
        }
        else l=mid+1;
    }
    pnodes=l;


    l=0;r=ans.size()-1;
    while(l<r)
    {
        int mid=(l+r)/2;
        vector<int>tmp;
        for(int i=l;i<=mid;i++)
        {
            tmp.push_back(ans[i]);
        }
        if(are_connected(tmp,{nodes[pnodes]}))
        {
            r=mid;
        }
        else l=mid+1;
    }
    pans=l;

    vector<int>nans;
    for(int i=pans+1;i<ans.size();i++)
    {
        nans.push_back(ans[i]);
    }
    for(int i=0;i<=pans;i++)
    {
        nans.push_back(ans[i]);
    }
    for(int i=pnodes;i<nodes.size();i++)
    {
        nans.push_back(nodes[i]);
    }
    for(int i=0;i<pnodes;i++)
    {
        nans.push_back(nodes[i]);
    }
    ans=nans;
}
void solve(vector<int>nodes,int u)//u=ans.back()
{
    if(nodes.size()==0)return;
    if(are_connected(nodes,{u})==0){special(nodes);return;}

    int l=0,r=nodes.size()-1;
    while(l<r)
    {
        int mid=(l+r)/2;
        vector<int>tmp;
        for(int i=l;i<=mid;i++)
        {
            tmp.push_back(nodes[i]);
        }
        if(are_connected(tmp,{u}))
        {
            r=mid;
        }
        else l=mid+1;
    }

    vector<int>other;
    int mid=(nodes.size()-1)/2;
    if(l<=mid)
    {
        for(int i=0;i<l;i++)other.push_back(nodes[i]);
        for(int i=l;i<nodes.size();i++)ans.push_back(nodes[i]);
        solve(other,ans.back());
    }
    else
    {
        for(int i=l;i>=0;i--)
        {
            ans.push_back(nodes[i]);
        }
        for(int i=l+1;i<nodes.size();i++)
        {
            other.push_back(nodes[i]);
        }
        solve(other,ans.back());
    }
}
std::vector<int> longest_trip(int N, int D)
{
    cntqueries=0;
    n=N;
    ans.clear();
    ///reset eveerything
    vector<int>v1,v2;

    vector<int>nodes;
    for(int i=0;i<n;i++)nodes.push_back(i);
    shuffle(nodes.begin(),nodes.end(),rng);
    v1.push_back(nodes.back());nodes.pop_back();v2.push_back(nodes.back());nodes.pop_back();
    for(int i:nodes)
    {
        vector<pair<int,int>>tmp;
        tmp.push_back({i,v1.back()});
        tmp.push_back({v1.back(),v2.back()});
        tmp.push_back({v2.back(),i});
        shuffle(tmp.begin(),tmp.end(),rng);

        for(int j=0;j<3;j++)
        {
            int x,y;
            tie(x,y)=tmp[j];
            if(j==2 or edge(x,y))
            {
                if(x==v1.back() && y==v2.back())
                {
                    vector<int>akka=v1;
                    reverse(v2.begin(),v2.end());
                    for(int x:v2)akka.push_back(x);
                    v1=akka;
                    v2.clear();v2.push_back(i);
                }
                else if(x==i)
                {
                    v1.push_back(i);
                }
                else v2.push_back(i);
                break;
            }
        }
    }
    if(v1.size()>v2.size())
    {
        ans=v1;
        solve(v2,v1.back());
    }
    else
    {
        ans=v2;
        solve(v1,v2.back());
    }
    if(cntqueries>400)while(1);
    return ans;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...