CF603EPastoral Oddities
发布时间:2020-12-14 02:02:35 所属栏目:Linux 来源:网络整理
导读:/*LCT管子题(说的就是你 水管局长)首先能得到一个结论,那就是当且仅当所有联通块都是偶数时存在构造方案LCT动态加边,维护最小生成联通块,用set维护可以删除的边,假如现在删除后不影响全都是偶数大小的性质 就删除不清楚link为啥要makeroot两次 */#includecst
/* LCT管子题(说的就是你 水管局长) 首先能得到一个结论,那就是当且仅当所有联通块都是偶数时存在构造方案 LCT动态加边,维护最小生成联通块,用set维护可以删除的边,假如现在删除后不影响全都是偶数大小的性质 就删除 不清楚link为啥要makeroot两次 */ #include<cstdio> #include<algorithm> #include<cstring> #include<iostream> #include<queue> #include<set> #include<cmath> #define ll long long #define M 400010 #define mmp make_pair using namespace std; int read() { int nm = 0,f = 1; char c = getchar(); for(; !isdigit(c); c = getchar()) if(c == '-') f = -1; for(; isdigit(c); c = getchar()) nm = nm * 10 + c - '0'; return nm * f; } int n,m,cnt,ln[M],rn[M]; struct LCT { int fa[M],ch[M][2],sz[M],rev[M],val[M],mx[M],pl[M],zz[M]; #define ls ch[x][0] #define rs ch[x][1] void pushup(int x) { sz[x] = sz[ls] + sz[rs] + zz[x] + 1; mx[x] = max(mx[ls],mx[rs]); pl[x] = (mx[x] == mx[ls]) ? pl[ls]: pl[rs]; if(val[x] > mx[x]) mx[x] = val[x],pl[x] = x; } bool isr(int x) { return ch[fa[x]][0] != x && ch[fa[x]][1] != x; } void add(int x) { rev[x] ^= 1; swap(ls,rs); } void pushdown(int x) { if(rev[x]) { add(ls),add(rs); rev[x] = 0; } } void pd(int x) { if(!isr(x)) pd(fa[x]); pushdown(x); } void rotate(int x) { int y = fa[x],q = fa[y]; bool dy = (ch[y][1] == x),dz = (ch[q][1] == y); if(!isr(y)) ch[q][dz] = x; fa[x] = q; fa[ch[x][dy ^ 1]] = y; ch[y][dy] = ch[x][dy ^ 1]; ch[x][dy ^ 1] = y; fa[y] = x; pushup(y); pushup(x); } void splay(int x) { pd(x); while(!isr(x)) { int y = fa[x]; if(!isr(y)) { int q = fa[y]; if((ch[y][1] == x) ^ (ch[q][1] == y)) rotate(x); else rotate(y); } rotate(x); } } void access(int x) { for(int y = 0; x; y = x,x = fa[x]) splay(x),zz[x] += sz[rs] - sz[y],rs = y,pushup(x); } void maker(int x) { access(x); splay(x); add(x); } int findr(int x) { access(x); splay(x); while(ls) pushdown(x),x = ls; return x; } void link(int x,int y) { maker(x); maker(y); fa[x] = y; zz[y] += sz[x]; sz[y] += sz[x]; } void split(int x,int y) { maker(x),access(y),splay(y); } void cut(int x,int y) { split(x,y); if(fa[x] != y && ch[x][1]) return; fa[x] = ch[y][0] = 0; pushup(y); } int query(int x,y); return pl[y]; } int sum(int x) { maker(x); return ((sz[x] + 1) >> 1) & 1; } } lct; set<pair<int,int> >st; set<pair<int,int> >::reverse_iterator it; int main() { n = read(),m = read(); cnt = n; // for(int i = 1; i <= n; i++) lct.sz[i] = 1; for(int i = 1; i <= m; i++) { int vi = read(),vj = read(); ln[i + n] = vi,rn[i + n] = vj; int x = read(); lct.val[i + n] = x; lct.pushup(i + n); if(lct.findr(vi) != lct.findr(vj)) { if(lct.sum(vi)) cnt--; if(lct.sum(vj)) cnt--; lct.link(vi,i + n); lct.link(i + n,vj); lct.split(vi,vj); if(lct.sum(vj)) cnt++; } else { int pl = lct.query(vi,vj); if(lct.val[pl] <= x) { if(cnt == 0) printf("%dn",st.rbegin()->first); else puts("-1"); continue; } lct.cut(ln[pl],pl); lct.cut(rn[pl],pl); lct.link(vi,vj); // lct.split(vi,vj); st.erase(st.find(mmp(lct.val[pl],pl))); } st.insert(mmp(x,i + n)); if(cnt) { puts("-1"); continue; } while(1) { it = st.rbegin(); int id = it->second; lct.cut(ln[id],id); lct.cut(id,rn[id]); if(lct.sum(ln[id]) || lct.sum(rn[id])) { lct.link(ln[id],id); lct.link(id,rn[id]); break; } st.erase(*it); } printf("%dn",st.rbegin()->first); } return 0; } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |