Submission #436074

#TimeUsernameProblemLanguageResultExecution timeMemory
436074TLP39Fountain Parks (IOI21_parks)C++17
100 / 100
421 ms68260 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[temp];
        }
    }
     
    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]==2)
            {
                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:39:22: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   39 |         for(int i=0;i<adj[v].size();i++)
      |                     ~^~~~~~~~~~~~~~
parks.cpp: In function 'void dfs_check(int)':
parks.cpp:50:22: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   50 |         for(int i=0;i<adj2[v].size();i++)
      |                     ~^~~~~~~~~~~~~~~
parks.cpp: In function 'int construct_roads(std::vector<int>, std::vector<int>)':
parks.cpp:170:22: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<std::pair<int, bool> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  170 |         for(int i=0;i<link.size();i++)
      |                     ~^~~~~~~~~~~~
parks.cpp:175:22: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<std::pair<int, bool> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  175 |         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...