QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#203609#4652. Minimum DiameteryiyiyiAC ✓623ms16624kbC++174.2kb2023-10-06 18:38:362023-10-06 18:38:37

Judging History

你现在查看的是最新测评结果

  • [2023-10-06 18:38:37]
  • 评测
  • 测评结果:AC
  • 用时:623ms
  • 内存:16624kb
  • [2023-10-06 18:38:36]
  • 提交

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