BZOJ2959——长跑
来源:互联网 发布:淘宝客佣金分成 编辑:程序博客网 时间:2024/04/25 18:23
1、题意:
2、分析:先来考虑那个最大路径是什么鬼。。一个环里面的点那么这个点都可以到对吧。。那就是缩环咯,这样就可以搞成一个树,缩环用并查集来做,每一次链接两个点,如果变成环就缩,不是就在树上玩,那么这个很显然可以使用lct+并查集来完成。
#include <map>#include <set>#include <stack>#include <cmath>#include <queue>#include <vector>#include <bitset>#include <string>#include <cstdio>#include <cstdlib>#include <cstring>#include <iostream>#include <algorithm>using namespace std;#define M 1000010#define LL long long#define MOD 1000000007#define inf 2147483647#define llinf 4000000000000000000ll#define For(i, x, y) for(int i = (x); i < (y); i ++)#define rep(i, x, y) for(int i = (x); i <= (y); i ++)#define drep(i, x, y) for(int i = (x); i >= (y); i --)inline int read(){ char ch=getchar();int x=0,f=1; while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while('0'<=ch&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f;}inline LL llread(){ char ch=getchar();LL x=0,f=1; while(ch<'0'||ch >'9'){if(ch=='-')f=-1;ch=getchar();} while('0'<=ch&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f;}struct Union{ int fa[M]; inline void init(int n){ rep(i, 1, n) fa[i] = i; } inline int find(int x){ return fa[x] == x ? x : fa[x] = find(fa[x]); } inline void merge(int x, int y){ int p = find(x), q = find(y); if(p != q) fa[p] = q; }} aa, bb;namespace LinkCutTree{ struct Node{ Node *ch[2], *fa; int val, sum, num; bool rev; Node(); inline int which(); inline void reverse(){ if(this){ rev ^= 1; swap(ch[0], ch[1]); } } inline void pd(){ if(rev){ ch[0] -> reverse(); ch[1] -> reverse(); rev = 0; } } inline void maintain(){ sum = ch[0] -> sum + ch[1] -> sum + val; } } *null, *pos[M], tree[M]; inline int Node::which(){ if(fa == null || (fa -> ch[0] != this && fa -> ch[1] != this)) return -1; return fa -> ch[1] == this; } Node::Node(){ rev = false; ch[0] = ch[1] = fa = null; sum = val = num = 0; } inline void rotate(Node *o){ Node *p = o -> fa; int l = o -> which(), r = l ^ 1; o -> fa = p -> fa; if(p -> which() != -1) p -> fa -> ch[p -> which()] = o; p -> ch[l] = o -> ch[r]; if(o -> ch[r]) o -> ch[r] -> fa = p; o -> ch[r] = p; p -> fa = o; o -> ch[r] -> maintain(); o -> maintain(); } inline void splay(Node *o){ static stack<Node*> st; Node *p = o; while(1){ st.push(p); if(p -> which() == -1) break; p = p -> fa; } while(!st.empty()){ st.top() -> pd(); st.pop(); } while(o -> which() != -1){ p = o -> fa; if(p -> which() != -1){ if(p -> which() ^ o -> which()) rotate(o); else rotate(p); } rotate(o); } } inline void Access(Node *o){ Node *y = null; while(o != null){ splay(o); o -> ch[1] = y; o -> maintain(); y = o; o -> fa = pos[bb.find(o -> fa -> num)]; o = o -> fa; } } inline void MovetoRoot(Node *o){ Access(o); splay(o); o -> reverse(); } inline void Link(Node *x, Node *y){ MovetoRoot(x); x -> fa = y; } inline void Cut(Node *x, Node *y){ MovetoRoot(x); Access(y); splay(y); y -> ch[0] = x -> fa = null; y -> maintain(); } inline void color(Node* &a, int b){ if(a == null) return; if(a -> num != b){ pos[b] -> val += a -> val; //a -> val = 0; } bb.merge(a -> num, b); color(a -> ch[0], b); color(a -> ch[1], b); a -> maintain(); //a = null; }}int value[M]; int main(){ //freopen("0input.in", "r", stdin); using namespace LinkCutTree; pos[0] = null = &tree[0]; int n = read(), m = read(); aa.init(n); bb.init(n); rep(i, 0, n){ tree[i].ch[0] = null; tree[i].ch[1] = null; tree[i].fa = null; } rep(i, 1, n){ pos[i] = &tree[i]; value[i] = pos[i] -> val = read(); pos[i] -> maintain(); pos[i] -> num = i; } while(m --){ int p = read(), a = read(), b = read(); if(p == 1){ a = bb.find(a), b = bb.find(b); if(aa.find(a) == aa.find(b)){ if(a == b) continue; MovetoRoot(pos[b]); Access(pos[a]); splay(pos[a]); color(pos[a], a); } else{ // puts("-1"); Link(pos[a], pos[b]); aa.merge(a, b); } } else if(p == 2){ int x = bb.find(a); splay(pos[x]); pos[x] -> val += b - value[a]; pos[x] -> maintain(); value[a] = b; } else{ a = bb.find(a), b = bb.find(b); if(aa.find(a) != aa.find(b)){ puts("-1"); continue; } MovetoRoot(pos[b]); Access(pos[a]); splay(pos[a]); printf("%d\n", pos[a] -> sum); } } return 0;}
0 0
- BZOJ2959——长跑
- bzoj2959: 长跑
- BZOJ2959: 长跑
- 【bzoj2959】长跑
- 【BZOJ2959】【codevs2002】长跑,维护双联通分量
- [BZOJ2959]长跑(lct+并查集)
- [BZOJ2959][清橙1379]长跑-LCT-并查集
- bzoj2959
- 长跑
- 长跑
- 《长跑秘籍——让你跑步距离增加一倍以上》有12个想法
- 结束长跑
- 在工作中长跑
- bzoj2959(LCT+缩点)
- 跳高和长跑
- 人生就是长跑
- 生活是长跑
- 人生如长跑
- maven构建项目引入jstl后还是报错
- ceph基本架构简述
- 函数的迭代
- jsp错误页面全局配置
- Zookeeper 集群搭建
- BZOJ2959——长跑
- Chrome NET::ERR_CERT_AUTHORITY_INVALID 错误分析及处理
- maven发布web项目时报错ClassNotFoundException
- unity 设置帧数
- 函数方程
- leetcode/2017-1-1
- PHP 基础五
- .net窗体或控件透明效果
- 魅族手机权限开启方法5