[LOJ # 3031. "JOISC 2019 Day1" party

LOJ # 3031. "JOISC 2019 Day1" party

I heard a randomly over?

I think for a long time thought of a card is not the practice, before the construction of a \ (u - 1 \) points imaginary tree, and then find the first \ (u \) insertion position points, is the time to find a longest chains, two chains endpoints query tree and imaginary u, u if u then find the binary position in the chain, if the point u and the chain is not attached to the chain and not on the chain, so that the construction is then connected to the point u, or delete the entire chain, retains the point u connected, continue this operation

Up to half of the cost should be 11, almost every deleted two sons 18/2 = 9

However, this limit is certainly not run up to the last data point measured the number of operations is 21000+, there are several points of 19,000 or so more than 10,000

There is also a 2000-point run in 1998 I do not know what happened

#include "meetings.h"
#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int,int>
#define mp make_pair
#define pb push_back
#define space putchar(' ')
#define enter putchar('\n')
#define eps 1e-10
#define MAXN 2005
#define ba 47
//#define ivorysi
using namespace std;
typedef long long int64;
typedef unsigned int u32;
typedef double db;
template<class T>
void read(T &res) {
    res = 0;T f = 1;char c = getchar();
    while(c < '0' || c > '9') {
    if(c == '-') f = -1;
    c = getchar();
    }
    while(c >= '0' && c <= '9') {
    res = res * 10 +c - '0';
    c = getchar();
    }
    res *= f;
}
template<class T>
void out(T x) {
    if(x < 0) {x = -x;putchar('-');}
    if(x >= 10) {
    out(x / 10);
    }
    putchar('0' + x % 10);
}
set<int> to[2005];
bool vis[2005],finish[2005];
int dep[2005],S,T,fa[2005];
vector<int> v,line;
void getpos(int u,int fa) {
    v.pb(u);
    for(auto v : to[u]) {
    if(vis[v]) continue;
    if(v != fa) getpos(v,u);
    }
}
void dfs(int u) {
    for(auto v : to[u]) {
    if(v != fa[u]) {
        dep[v] = dep[u] + 1;
        fa[v] = u;
        dfs(v);
    }
    }
}
void getpara(int p) {
    v.clear();
    getpos(p,-1);
    dep[p] = 0;fa[p] = -1;
    dfs(p);
    S = p;
    for(auto t : v) {
    if(dep[t] > dep[S]) S = t;
    }
    dep[S] = 0;fa[S] = -1;
    dfs(S);
    T = p;
    for(auto t : v) {
    if(dep[t] > dep[T]) T = t;
    }
}
void pass_line(int a,int b) {
    dep[a] = 0;fa[a] = -1;
    dfs(a);
    int p = b;
    while(1) {
    vis[p] = 1;
    if(p == a) break;
    p = fa[p];
    }
}
void getline(int a,int b) {
    line.clear();
    dep[a] = 0;fa[a] = -1;
    dfs(a);
    int p = b;
    while(1) {
    line.pb(p);
    if(p == a) break;
    p = fa[p]; 
    }
}
void build(int u) {
    memset(vis,0,sizeof(vis));
    finish[u] = 1;
    int p = 0;
    while(1) {
    getpara(p);
    if(S == T) {
        to[S].insert(u);to[u].insert(S);break;
    }
    int m = Query(u,S,T);
    getline(S,T);
    bool f = 0;
    for(auto v : line) {
        if(v == m) {f = 1;break;}
    }
    if(!f && m != u) {
        build(m);to[m].insert(u);to[u].insert(m);break;
    }
    if(m == S) {to[u].insert(S);to[S].insert(u);break;}
    if(m == T) {to[u].insert(T);to[T].insert(u);break;}
    if(m == u) {
        
        int l = 1,r = line.size() - 1;
        while(l < r) {
        int mid = (l + r) >> 1;
        if(Query(u,line[mid],line[0]) == u) r = mid;
        else l = mid + 1;
        }
        int a = line[r],b = line[r - 1];
        to[b].erase(a);to[a].erase(b);
        to[b].insert(u);to[a].insert(u);
        to[u].insert(a);to[u].insert(b);
        break;
    }
    p = m;pass_line(S,T);vis[p] = 0;
    }
}
void Solve(int N) {
    to[0].insert(1);to[1].insert(0);
    for(int i = 2 ; i < N ; ++i) {
    if(!finish[i]) build(i);
    }
    for(int i = 0 ; i < N ; ++i) {
    for(auto v : to[i]) {
        if(v > i) Bridge(i,v);
    }
    }
}

Guess you like

Origin www.cnblogs.com/ivorysi/p/10947459.html