#include<iostream>
#include<vector>
#include<cstring>
#include<algorithm>
#include<set>
#include<random>
#include "sphinx.h"
//#include "grader.cpp"
using namespace std;
const int MAX_N=252;
int n;
vector<int>g[MAX_N];
vector<int>exp1,ans;
set<int>idseven,idsodd;
int cols[MAX_N];
vector<int>dif;
int queryN[2][MAX_N][MAX_N];
int query[2][MAX_N][MAX_N];
bool used[MAX_N];
int depth[MAX_N];
bool init=1;
void dfs(int u)
{
    used[u]=1;
    for(int v:g[u])
    {
        if(used[v] or cols[v]==0)continue;
        if(init)depth[v]=depth[u]+1;
        dfs(v);
    }
}
int comps()
{
    int cmps=0;
    for(int i=0;i<n;i++)used[i]=0;
    for(int i=0;i<n;i++)
    {
        if(!used[i] && cols[i])
        {
            cmps++;
            dfs(i);
        }
    }
    return cmps;
}
bool check(bool wh,int l,int r,set<int>ids,int col)
{
    bool full=1;
    for(int id:ids)
    {
        if(ans[id]==-1)full=0;
    }
    if(full)return 0;
    if(ids.size()==1)
    {
        for(int i=0;i<n;i++)exp1[i]=col;
        exp1[(*(ids.begin()))]=-1;
        if(perform_experiment(exp1)==1)
        {
            return 1;
        }
        return 0;
    }
    for(int i=0;i<n;i++)exp1[i]=col;
    for(int id:ids)
    {
        if(ans[id]==-1)exp1[id]=-1;
    }
    if(query[wh][l][r]==-1)
    {
        query[wh][l][r]=perform_experiment(exp1);
    }
    int cnt=query[wh][l][r];
    if(queryN[wh][l][r]<=-1)
    {
        int x=-1-queryN[wh][l][r];
        vector<int>exp2;exp2.resize(n);
        for(int i=0;i<n;i++)exp2[i]=n;
        for(int id:ids)exp2[id]=-1;
        queryN[wh][l][r]=perform_experiment(exp2)-x;
    }
    int cntN=queryN[wh][l][r];
    if(cnt<cntN)return 1;
    return 0;
}
set<int>tmp;
void colour(bool wh,int l,int r,set<int>ids,int u,int col)
{
    ans[u]=col;
    bool full=1;
    for(int id:ids)
    {
        if(ans[id]==-1)full=0;
    }
    if(full)
    {
        return;
        vector<int>tocolour;
        for(int v:g[u])
        {
            if(dif[v]==dif[u] && ans[v]==-1)
            {
                if((depth[v]%2==0 && wh==0) or (depth[v]%2==1 && wh==1))
                {
                    tocolour.push_back(v);
                }
                else tmp.insert(v);
            }
        }
        for(int v:tocolour)
        {
            if(ans[v]!=-1)continue;
            set<int>idsreal;
            if(wh==0)idsreal=idseven;
            else idsreal=idsodd;
            colour(wh,0,idsreal.size()-1,idsreal,v,col);
        }
        return;
    }
    int uni=1;
    for(int v:g[u])
    {
        if(ans[v]==-1 && ids.count(v) && dif[v]==dif[u])
        {
            uni=0;
            break;
        }
    }
    for(int i=0;i<n;i++)
    {
        cols[i]=1;
    }
    for(int id:ids)
    {
        if(ans[id]==-1)cols[id]=0;
    }
    cols[u]=0;
    int diff=comps();
    cols[u]=1;
    diff=diff-comps();
    queryN[wh][l][r]-=(uni+diff);
    int mid=(ids.size()-1)/2;
    vector<int>idd;
    for(int id:ids)idd.push_back(id);
    set<int>ids1,ids2;
    for(int i=0;i<ids.size();i++)
    {
        if(i<=mid)ids1.insert(idd[i]);
        else ids2.insert(idd[i]);
    }
    mid=(l+r)/2;
    if(ids1.count(u))colour(wh,l,mid,ids1,u,col);
    else colour(wh,mid+1,r,ids2,u,col);
}
void rec(bool wh,int l,int r,set<int>ids,int col)
{
    if(ids.size()==1)
    {
        set<int>idsreal;
        if(wh==0)idsreal=idseven;
        else idsreal=idsodd;
        colour(wh,0,idsreal.size()-1,idsreal,(*(ids.begin())),col);
        return;
    }
    int mid=(ids.size()-1)/2;
    vector<int>idd;
    for(int id:ids)idd.push_back(id);
    set<int>ids1,ids2;
    for(int i=0;i<ids.size();i++)
    {
        if(i<=mid)ids1.insert(idd[i]);
        else ids2.insert(idd[i]);
    }
    mid=(l+r)/2;
    /*bool full=1;
    for(int id:ids1)
    {
        if(ans[id]==-1)full=0;
    }
    if(full){rec(wh,mid+1,r,ids2,col);return;}
    full=1;
    for(int id:ids2)
    {
        if(ans[id]==-1)full=0;
    }
    if(full){rec(wh,l,mid,ids1,col);return;}*/
    if(check(wh,l,mid,ids1,col))rec(wh,l,mid,ids1,col);
    else rec(wh,mid+1,r,ids2,col);
}
vector<vector<int>>nodescol;
vector<int>uniq;
bool alone(int l,int r,int i)
{
    for(int u=0;u<n;u++){cols[u]=1;exp1[u]=n;}
    cols[i]=0;
    exp1[i]=-1;
    for(int c=l;c<=r;c++)
    {
        for(int u:nodescol[uniq[c]])
        {
            cols[u]=0;
            exp1[u]=-1;
        }
    }
    int cmps=comps()+(r-l+1)+1;
    if(perform_experiment(exp1)<cmps)return 0;
    return 1;
}
void different()
{
    for(int i=1;i<n;i++)
    {
        nodescol.clear();
        nodescol.resize(n);
        uniq.clear();
        for(int v:g[i])
        {
            if(v<i)
            {
                if(nodescol[dif[v]].size()==0)
                {
                    uniq.push_back(dif[v]);
                }
                nodescol[dif[v]].push_back(v);
            }
        }
        int l=0,r=uniq.size()-1;
        if(alone(l,r,i))
        {
            dif[i]=i;
            continue;
        }
        int firsteq;
        while(l<r)
        {
            int mid=(l+r)/2;
            if(alone(l,mid,i))
            {
                l=mid+1;
            }
            else
            {
                r=mid;
            }
        }
        firsteq=l;
        dif[i]=uniq[firsteq];
    }
}
std::vector<int> find_colours(int N, std::vector<int> X, std::vector<int> Y)
{
    n=N;
    exp1.resize(n);ans.resize(n);dif.resize(n);
    for(int i=0;i<n;i++){cols[i]=1;ans[i]=-1;}
    for(int i=0;i<X.size();i++)
    {
        g[X[i]].push_back(Y[i]);
        g[Y[i]].push_back(X[i]);
    }
    dfs(0);
    init=0;
    different();
    for(int i=0;i<n;i++)
    {
        for(int j=i;j<n;j++)
        {
            queryN[0][i][j]=-1;
            queryN[1][i][j]=-1;
        }
    }
    for(int i=0;i<n;i++)
    {
        if(ans[i]==-1 && depth[i]%2==0)idseven.insert(i);
    }
    for(int i=0;i<n;i++)
    {
        if(ans[i]==-1 && depth[i]%2==1)idsodd.insert(i);
    }
    for(int col=0;col<n;col++)
    {
        for(int i=0;i<n;i++)
        {
            for(int j=i;j<n;j++)
            {
                query[0][i][j]=-1;
                query[1][i][j]=-1;
            }
        }
        tmp.clear();
        while(1)
        {
            bool full=1;
            for(int id:idseven)
            {
                if(ans[id]==-1)full=0;
            }
            if(full)break;
            if(check(0,0,idseven.size()-1,idseven,col))rec(0,0,idseven.size()-1,idseven,col);
            else break;
        }
        for(int u:tmp)
        {
            colour(1,0,idsodd.size()-1,idsodd,u,col);
        }
        while(1)
        {
            bool full=1;
            for(int id:idsodd)
            {
                if(ans[id]==-1)full=0;
            }
            if(full)break;
            if(check(1,0,idsodd.size()-1,idsodd,col))rec(1,0,idsodd.size()-1,idsodd,col);
            else break;
        }
    }
    return ans;
}
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... |