Submission #859980

#TimeUsernameProblemLanguageResultExecution timeMemory
859980abcvuitunggioSplit the Attractions (IOI19_split)C++17
40 / 100
93 ms32968 KiB
#include "split.h"
#include <bits/stdc++.h>
using namespace std;
int n,a,b,c,label[3]={1,2,3},d[100001],up[100001],sz[100001],vis[100001],node,t,f[100001],ch[100001],tin[100001],tout[100001];
vector <int> ke[100001],child[100001],del2[100001],res,ve;
vector <pair <int, int>> add[100001],del[100001];
void dfs(int u){
    tin[u]=++t;
    vis[u]=sz[u]=1;
    for (int v:ke[u])
        if (!vis[v]){
            child[u].push_back(v);
            d[v]=d[u]+1;
            up[v]=u;
            dfs(v);
            sz[u]+=sz[v];
        }
    tout[u]=t;
}
void dfs2(int u, int cur, int i){
    if (d[up[u]]<d[cur]){
        add[cur].push_back({u,i});
        del[up[u]].push_back({u,i});
        cur=up[u];
    }
    for (int v:child[u])
        dfs2(v,cur,i);
}
void dfs3(int u){
    if (ch[u])
        return;
    ve.push_back(u);
    for (int v:child[u])
        dfs3(v);
}
void update(int i, int val){
    i++;
    for (;i<=n;i+=i&(-i))
        f[i]+=val;
}
int get(int i){
    i++;
    int res=0;
    for (;i;i-=i&(-i))
        res+=f[i];
    return res;
}
bool check(int l, int r){
    vector <int> ve;
    set <pair <int, int>> s;
    set <int> s2;
    for (int i=0;i<n;i++){
        if (sz[i]>=l&&sz[i]<=r){
            node=i;
            return true;
        }
        add[i].clear();
        del[i].clear();
        del2[i].clear();
        if (sz[i]>r)
            ve.push_back(i);
    }
    memset(f,0,sizeof(f));
    memset(ch,0,sizeof(ch));
    sort(ve.begin(),ve.end(),[](int i, int j){return d[i]<d[j];});
    for (int i=0;i<ve.size();i++){
        for (int j:child[ve[i]])
            if (sz[j]<l)
                dfs2(j,ve[i],i);
        del2[up[ve[i]]].push_back(i);
    }
    s.insert({0,ve.size()});
    for (int i=ve.size()-1;i>=0;i--){
        for (auto [j,k]:del[ve[i]]){
            update(k,-sz[j]);
            s2.erase(j);
        }
        for (auto [j,k]:add[ve[i]]){
            update(k,sz[j]);
            s2.insert(j);
        }
        for (int j:del2[ve[i]])
            s.erase({-sz[ve[j]],j});
        auto it=s.lower_bound({a-sz[ve[i]],-1});
        auto [val,pos]=*it;
        if (sz[ve[i]]+val<=b){
            node=ve[i];
            ch[ve[pos]]=1;
            return true;
        }
        if (sz[ve[i]]+val-get(pos-1)<=b){
            node=ve[i];
            ch[ve[pos]]=1;
            int cnt=sz[ve[i]]+val;
            for (int j:s2){
                if (pos<ve.size()&&tin[ve[pos]]<=tin[j]&&tout[ve[pos]]>=tout[j])
                    continue;
                cnt-=sz[j];
                ch[j]=1;
                if (cnt<=r)
                    break;
            }
            return true;
        }
        s.insert({-sz[ve[i]],i});
    }
    return false;
}
vector <int> find_split(int N, int A, int B, int C, vector <int> p, vector <int> q){
	n=N,a=A,b=B,c=C;
	if (a>b){
        swap(a,b);
        swap(label[0],label[1]);
	}
	if (b>c){
        swap(b,c);
        swap(label[1],label[2]);
	}
	if (a>b){
        swap(a,b);
        swap(label[0],label[1]);
	}
	for (int i=0;i<p.size();i++){
        ke[p[i]].push_back(q[i]);
        ke[q[i]].push_back(p[i]);
	}
	dfs(0);
    for (int i=0;i<n;i++)
        for (int j:ke[i])
            if (d[j]<d[up[i]])
                up[i]=j;
    res.assign(n,0);
    if (check(b,n-a)){
        swap(a,b);
        swap(label[0],label[1]);
    }
    else if (!check(a,n-b))
        return res;
    dfs3(node);
    sort(ve.begin(),ve.end(),[](int i, int j){return d[i]<d[j];});
    for (int i=0;i<ve.size();i++)
        res[ve[i]]=label[(i>=a)*2];
    ve.clear();
    for (int i=0;i<n;i++)
        if (!res[i])
            ve.push_back(i);
    queue <int> Q;
    memset(d,0,sizeof(d));
    d[ve[0]]=1;
    Q.push(ve[0]);
    while (!Q.empty()){
        int u=Q.front();
        Q.pop();
        for (int v:ke[u])
            if (!res[v]&&!d[v]){
                d[v]=d[u]+1;
                Q.push(v);
            }
    }
    sort(ve.begin(),ve.end(),[](int i, int j){return d[i]<d[j];});
    for (int i=0;i<ve.size();i++)
        res[ve[i]]=label[(i>=b)+1];
    return res;
}

Compilation message (stderr)

split.cpp: In function 'bool check(int, int)':
split.cpp:66:19: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   66 |     for (int i=0;i<ve.size();i++){
      |                  ~^~~~~~~~~~
split.cpp:96:24: warning: comparison of integer expressions of different signedness: 'std::tuple_element<1, std::pair<int, int> >::type' {aka 'int'} and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   96 |                 if (pos<ve.size()&&tin[ve[pos]]<=tin[j]&&tout[ve[pos]]>=tout[j])
      |                     ~~~^~~~~~~~~~
split.cpp: In function 'std::vector<int> find_split(int, int, int, int, std::vector<int>, std::vector<int>)':
split.cpp:123:16: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  123 |  for (int i=0;i<p.size();i++){
      |               ~^~~~~~~~~
split.cpp:141:19: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  141 |     for (int i=0;i<ve.size();i++)
      |                  ~^~~~~~~~~~
split.cpp:161:19: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  161 |     for (int i=0;i<ve.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...