Submission #859935

#TimeUsernameProblemLanguageResultExecution timeMemory
859935abcvuitunggioSplit the Attractions (IOI19_split)C++17
11 / 100
103 ms34020 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,sum,f[100001],ch[100001];
vector <int> ke[100001],child[100001],del2[100001],res,ve;
vector <pair <int, int>> add[100001],del[100001];
void dfs(int u){
    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];
        }
}
void dfs2(int u, int cur, int i){
    if (d[up[u]]<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);
        s.insert({-sz[ve[i]],i});
        del2[up[ve[i]]].push_back(i);
    }
    sum=0;
    s.insert({0,ve.size()});
    for (int i=ve.size()-1;i>=0;i--){
        for (auto [j,k]:del[i]){
            update(k,-sz[j]);
            s2.insert(j);
        }
        for (auto [j,k]:add[i]){
            update(k,sz[j]);
            s2.erase(j);
        }
        for (int j:del2[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=i;
            ch[ve[pos]]=1;
            return true;
        }
        if (sz[ve[i]]+val-get(pos-1)+get(i-1)<=b){
            node=i;
            ch[ve[pos]]=1;
            int cnt=sz[ve[i]]+val;
            for (int j:s2){
                cnt-=sz[j];
                ch[j]=1;
                if (cnt<=b)
                    break;
            }
            return true;
        }
    }
    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<a;i++)
        res[ve[i]]=label[0];
    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:64:19: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   64 |     for (int i=0;i<ve.size();i++){
      |                  ~^~~~~~~~~~
split.cpp: In function 'std::vector<int> find_split(int, int, int, int, std::vector<int>, std::vector<int>)':
split.cpp:120:16: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  120 |  for (int i=0;i<p.size();i++){
      |               ~^~~~~~~~~
split.cpp:158:19: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  158 |     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...