Submission #435807

#TimeUsernameProblemLanguageResultExecution timeMemory
435807TLP39Fountain Parks (IOI21_parks)C++17
70 / 100
373 ms68228 KiB
#include "parks.h"
#include<bits/stdc++.h>
using namespace std;
typedef pair<pair<int,int>,int> pp;
int n;
///bench position
int bench_lr[200010]={},bench_ba[200010]={};
///above,below,left,right;
int a[200010],b[200010],l[200010],r[200010];
///sort to get a b l r
vector<pp> fo,fo2;
///go back to find links: traceback above and below (get the x coor)
int trace_a[200010],trace_b[200010];
///to get potential connected links (that shouldn't collide)
int cur_y[200010],cur_x[200010];
vector<pair<int,bool>> link;
vector<int> adj[400010];
int chosen[400010]={};
///check if every fountains are connected
vector<int> adj2[200010];

void changebench(int x)
{
    if(x<0) return;
    if(a[x]<0) return;
    int temp=x;
    while(temp>=0 && a[temp]>=0 && bench_lr[temp]==-1)
    {
        bench_lr[temp]=1;
        temp=r[x];
    }
}

void dfs(int v,int col)
{
    chosen[v]=col;
    for(int i=0;i<adj[v].size();i++)
    {
        if(!chosen[adj[v][i]]) dfs(adj[v][i],3-col);
    }
}

int cou=0;
bool visited[200010]={};
void dfs_check(int v)
{
    cou++;
    for(int i=0;i<adj2[v].size();i++)
    {
        if(visited[adj2[v][i]]) continue;
        visited[adj2[v][i]]=true;
        dfs_check(adj2[v][i]);
    }
}

int construct_roads(std::vector<int> x, std::vector<int> y) {
    if (x.size() == 1) {
	build({}, {}, {}, {});
        return 1;
    }
    n=x.size();
    for(int i=0;i<n;i++)
    {
        fo.push_back({{x[i],y[i]},i});
        fo2.push_back({{y[i],x[i]},i});
        a[i]=-1;
        b[i]=-1;
        l[i]=-1;
        r[i]=-1;
    }
    for(int i=0;i<200010;i++) cur_x[i]=cur_y[i]=-2;
    sort(fo.begin(),fo.end());
    sort(fo2.begin(),fo2.end());
    for(int i=0;i<n-1;i++)
    {
        if(fo[i].first.first==fo[i+1].first.first && fo[i].first.second==fo[i+1].first.second-2)
        {
            a[fo[i].second]=fo[i+1].second;
            b[fo[i+1].second]=fo[i].second;
            bench_lr[fo[i].second]=-1;
        }
    }
    for(int i=0;i<n-1;i++)
    {
        if(fo2[i].first.first==fo2[i+1].first.first && fo2[i].first.second==fo2[i+1].first.second-2)
        {
            r[fo2[i].second]=fo2[i+1].second;
            l[fo2[i+1].second]=fo2[i].second;
        }
    }
    for(int i=0;i<n;i++)
    {
        if(a[i]>=0) adj2[i].push_back(a[i]);
        if(b[i]>=0) adj2[i].push_back(b[i]);
        if(l[i]>=0) adj2[i].push_back(l[i]);
        if(r[i]>=0) adj2[i].push_back(r[i]);
    }
    visited[0]=true;
    dfs_check(0);
    if(cou<n) return 0;
    int temp;
    for(int i=0;i<n-1;i++)
    {
        temp=fo[i].second;
        if(a[temp]<0)
        {
            trace_a[temp]=x[temp]+1;
        }
        else
        {
            if(l[temp]<0)
            {
                trace_a[temp]=x[temp]-1;
            }
            else
            {
                trace_a[temp]=trace_a[l[temp]];
            }
        }
        if(b[temp]<0)
        {
            trace_b[temp]=x[temp]+1;
        }
        else
        {
            if(l[temp]<0) trace_b[temp]=x[temp]-1;
            else trace_b[temp]=trace_b[l[temp]];
        }
    }
    int temp2;
    for(int i=0;i<n;i++)
    {
        temp=fo[i].second;
        if(r[temp]<0) continue;
        if(b[temp]<0 || b[r[temp]]<0)
        {
            link.push_back({temp,false});
            if(cur_y[y[temp]-1]>=0)
            {
                temp2=link[cur_y[y[temp]-1]].first;
                if(trace_b[temp]<=x[temp2]+1)
                {
                    adj[link.size()-1].push_back(cur_y[y[temp]-1]);
                    adj[cur_y[y[temp]-1]].push_back(link.size()-1);
                }
            }
            cur_y[y[temp]-1]=link.size()-1;
            cur_x[x[temp]+1]=link.size()-1;
        }
        if(a[temp]<0 || a[r[temp]]<0)
        {
            link.push_back({temp,true});
            if(cur_y[y[temp]+1]>=0)
            {
                temp2=link[cur_y[y[temp]+1]].first;
                if(trace_a[temp]<=x[temp2]+1)
                {
                    adj[link.size()-1].push_back(cur_y[y[temp]+1]);
                    adj[cur_y[y[temp]+1]].push_back(link.size()-1);
                }
            }
            cur_y[y[temp]+1]=link.size()-1;
            adj[link.size()-1].push_back(cur_x[x[temp]+1]);
            adj[cur_x[x[temp]+1]].push_back(link.size()-1);
            cur_x[x[temp]+1]=link.size()-1;
        }
    }
    for(int i=0;i<link.size();i++)
    {
        if(chosen[i]) continue;
        dfs(i,1);
    }
    for(int i=0;i<link.size();i++)
    {
        if(chosen[i]==1)
        {
            temp=link[i].first;
            if(link[i].second)
            {
                bench_ba[temp]=1;
                changebench(r[temp]);
            }
            else
            {
                bench_ba[temp]=-1;
                changebench(b[r[temp]]);
            }
        }
    }
    vector<int> u,v,aa,bb;
    for(int i=0;i<n;i++)
    {
        if(bench_lr[i])
        {
            u.push_back(i);
            v.push_back(a[i]);
            aa.push_back(x[i]+bench_lr[i]);
            bb.push_back(y[i]+1);
        }
        if(bench_ba[i])
        {
            u.push_back(i);
            v.push_back(r[i]);
            aa.push_back(x[i]+1);
            bb.push_back(y[i]+bench_ba[i]);
        }
    }
    build(u,v,aa,bb);
    return 1;
}

Compilation message (stderr)

parks.cpp: In function 'void dfs(int, int)':
parks.cpp:37:18: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   37 |     for(int i=0;i<adj[v].size();i++)
      |                 ~^~~~~~~~~~~~~~
parks.cpp: In function 'void dfs_check(int)':
parks.cpp:48:18: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   48 |     for(int i=0;i<adj2[v].size();i++)
      |                 ~^~~~~~~~~~~~~~~
parks.cpp: In function 'int construct_roads(std::vector<int>, std::vector<int>)':
parks.cpp:168:18: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<std::pair<int, bool> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  168 |     for(int i=0;i<link.size();i++)
      |                 ~^~~~~~~~~~~~
parks.cpp:173:18: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<std::pair<int, bool> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  173 |     for(int i=0;i<link.size();i++)
      |                 ~^~~~~~~~~~~~
#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...
#Verdict Execution timeMemoryGrader output
Fetching results...