QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#203609 | #4652. Minimum Diameter | yiyiyi | AC ✓ | 623ms | 16624kb | C++17 | 4.2kb | 2023-10-06 18:38:36 | 2023-10-06 18:38:37 |
Judging History
answer
#include<bits/stdc++.h>
#define ll long long
#define rep(i,s,t) for(int i=(s);i<=(t);i++)
#define rev_rep(i,s,t) for(int i=(s);i>=(t);i--)
using namespace std;
int ci(){
int x; scanf("%d",&x); return x;
}
enum{N=200023};
struct dt{ int sz; };
dt NIL = (dt){0};
dt operator+(const dt&a,const dt&b){
return (dt){a.sz+b.sz};
}
class LCT{
private:
struct node{
node*fa,*c[2];
dt x,x0;
bool rev;
#define lch c[0]
#define rch c[1]
void update(){
x = lch->x + x0 + rch->x;
}
void downdate(){
if( rev ){
lch->rev^=1, rch->rev^=1;
swap(lch,rch), rev=0;
}
}
}d[N];
bool chk(node*e){ return e->fa->rch==e; }
bool nroot(node*e){
return e->fa!=d&&(e->fa->lch==e||e->fa->rch==e);
}
node*get(node*x,bool o,node*y){
return x->c[o]=y, y->fa=x;
}
void rotate(node*e){
bool o = chk(e), ox= chk(e->fa);
node*x = e->fa, *y = x->fa, *w = e->c[o^1];
( nroot(x) ? y->c[ox]=e:0 ), e->c[o^1]=x, x->c[o]=w;
( w!=d ? w->fa=x:0 ), x->fa=e, e->fa=y;
x->update(), e->update();
}
void Downdate(node*e){
if( nroot(e) ) Downdate(e->fa);
e->downdate();
d->x = d->x0 = NIL;
}
node*splay(node*e){
Downdate(e);
while( nroot(e) ){
node*x = e->fa;
if( nroot(x) ) rotate(chk(e)^chk(x)?e:x);
rotate(e);
} return e;
}
node*access(node*x){
node*y=d;
for(;x!=d;y=x,x=x->fa){
splay(x), get(x,1,y), x->update();
} return y;
}
node*makeroot(node*e){
access(e), splay(e), e->rev^=1;
return e;
}
node*findroot(node*e){
access(e), splay(e);
while( 1 ){
e->downdate();
if( e->lch==d ) break;
e = e->lch;
} return splay(e);
}
void link(node*x,node*y){
makeroot(x)->fa = y;
}
void cut(node*x,node*y){
makeroot(x), access(y), splay(y), y->lch=x->fa=d, x->update();
}
node*split(node*x,node*y){
makeroot(x), access(y); return splay(y);
}
public:
void init(int n){
*d = (node){d,d,d,NIL,NIL};
rep(i,1,n) d[i] = (node){d,d,d,(dt){1},(dt){1}};
}
bool chk(int x,int y){
return findroot(d+x)==findroot(d+y);
}
void add(int x,int y){
link(d+x, d+y);
}
dt query(int x,int y){
return split(d+x,d+y)->x;
}
};
int a[N],b[N],d[N];
class UNI{
public:
int fa[N];
void init(int n){
rep(i,1,n) fa[i] = i, a[i] = b[i] = i, d[i] = 0;
}
int fd(int x){
return fa[x]==x ? x : fa[x]=fd(fa[x]);
}
int operator[](int x){ return fd(x); }
bool merge(int x,int y){
int fx=fd(x), fy=fd(y);
if( fx!=fy ){
fa[fx] = fy;
return 1;
} return 0;
}
};
LCT lct;
UNI uni;
//#define DEBUG
#ifndef DEBUG
#define chk_max(x,y) (x<y ? (x=y,1):0)
#define chk_min(x,y) (x>y ? (x=y,1):0)
#endif // DEBUG
#ifdef DEBUG
#define _chk_max(x,y) (x<y ? (x=y,1):0)
#define _chk_min(x,y) (x>y ? (x=y,1):0)
#define chk_max(x,y) if( _chk_max(x,y) )
#define chk_min(x,y) if( _chk_min(x,y) )
#endif // DEBUG
multiset<int, greater<int> > st;
signed main(){
int T = ci();
while( T-- ){
int n = ci(), m = ci();
lct.init(n);
uni.init(n);
st.clear();
rep(i,1,n) st.insert(d[i]);
st.insert(-1e9);
st.insert(-1e9);
rep(i,1,m){
int x = ci(), y = ci();
int fx= uni[x], fy = uni[y];
st.erase(st.lower_bound(d[fx]));
st.erase(st.lower_bound(d[fy]));
lct.add(x,y);
vector<pair<int,int> > vec = {
{a[fx], a[fy]},
{a[fx], b[fy]},
{b[fx], a[fy]},
{b[fx], b[fy]},
};
int ans = d[fx];
pair<int,int> pa = {a[fx], b[fx]};
if( d[fx] < d[fy] ){
ans = d[fy];
pa = {a[fy], b[fy]};
}
for(auto p:vec){
//printf("line %d: [%d %d] %d\n", __LINE__, p.first, p.second, lct.query(p.first, p.second).sz-1);
if( chk_max(ans, lct.query(p.first, p.second).sz-1) ) pa = p;
}
//printf("line %d: d ab %d %d %d \n", __LINE__, d[fy], a[fy], b[fy]);
uni.merge(fx,fy);
d[fy] = ans;
a[fy] = pa.first;
b[fy] = pa.second;
//printf("line %d: d ab %d %d %d \n", __LINE__, d[fy], a[fy], b[fy]);
st.insert(ans);
//printf("line %d:\n", __LINE__);
//for(auto x:st) printf("%d ", x); puts("");
int t1 = *st.begin();
int t2 = *(++st.begin());
int t3 = *(++(++st.begin()));
printf("%d\n", max(max(t1,(t1+1)/2+(t2+1)/2+1), (t2+1)/2+(t3+1)/2+2));
}
}
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 623ms
memory: 16624kb
input:
210 2 1 1 2 10 6 1 2 2 3 4 5 5 6 7 8 8 9 12 9 1 2 2 3 3 4 5 6 6 7 7 8 9 10 10 11 11 12 10 5 1 2 2 3 3 4 4 5 5 6 996 993 2 1 3 2 4 3 5 4 6 5 7 6 8 7 9 8 10 9 11 10 12 11 13 12 14 13 15 14 16 15 17 16 18 17 19 18 20 19 21 20 22 21 23 22 24 23 25 24 26 25 27 26 28 27 29 28 30 29 31 30 32 31 33 32 34 33...
output:
1 2 2 3 3 4 4 2 2 3 4 4 5 5 5 6 2 2 3 4 5 2 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 ...
result:
ok 750123 lines