zoukankan      html  css  js  c++  java
  • (右偏树)Bzoj2333: [SCOI2011]棘手的操作

    题面

    戳我

    Sol

    右偏树滑稽+并查集
    再在全局开一个可删除的堆(priority_queue)
    注意细节

    # include <bits/stdc++.h>
    # define RG register
    # define IL inline
    # define Fill(a, b) memset(a, b, sizeof(a))
    using namespace std;
    typedef long long ll;
    const int _(3e5 + 10);
    
    IL ll Read(){
    	RG ll x = 0, z = 1; RG char c = getchar();
    	for(; c < '0' || c > '9'; c = getchar()) z = c == '-' ? -1 : 1;
    	for(; c >= '0' && c <= '9'; c = getchar()) x = (x << 1) + (x << 3) + (c ^ 48);
    	return x * z;
    }
    
    int n, a[_], fa[_], add, S[_], top, rt[_];
    struct Right_Heap{	int fa, ls, rs, dis, val, tag;  } t[_];
    struct Heap{
    	priority_queue <int> A, B;
    	IL void Push(RG int x){  A.push(x);  }
    	
    	IL void Del(RG int x){  B.push(x);  }
    
    	IL int Top(){  while(!B.empty() && A.top() == B.top()) A.pop(), B.pop(); return A.top();  }
    } Q;
    
    IL void Update(RG int x){  t[x].dis = t[t[x].ls].dis + 1;  }
    
    IL void Adjust(RG int x){  if(t[t[x].ls].dis > t[t[x].rs].dis) swap(t[x].ls, t[x].rs);  }
    
    IL void Add(RG int x, RG int d){  if(!x) return; t[x].tag += d; t[x].val += d;   }
    
    IL void Pushdown(RG int x){  if(!t[x].tag) return; Add(t[x].ls, t[x].tag); Add(t[x].rs, t[x].tag); t[x].tag = 0;  }
    
    IL int Find(RG int x){  return fa[x] == x ? x : fa[x] = Find(fa[x]);  }
    
    IL int Merge(RG int x, RG int y){
    	if(!x || !y) return x + y;
    	Pushdown(x); Pushdown(y);
    	if(t[x].val < t[y].val) swap(x, y);
    	RG int tmp = Merge(t[x].ls, y);
    	t[tmp].fa = x; t[x].ls = tmp;
    	Adjust(x); Update(x);
    	return x;
    }
    
    IL void Pushall(RG int x){	for(RG int y = x; y; y = t[y].fa) S[++top] = y;	while(top) Pushdown(S[top--]);  }
    
    IL void Modify(RG int x, RG int d){
    	Pushall(x);
    	RG int tmp = Merge(t[x].ls, t[x].rs);
    	if(t[x].fa){
    		if(t[t[x].fa].ls == x) t[t[x].fa].ls = tmp;
    		else t[t[x].fa].rs = tmp;
    		for(RG int y = t[x].fa; y; y = t[y].fa)	Adjust(y), Update(y);
    	}
    	t[tmp].fa = t[x].fa; t[x].fa = t[x].ls = t[x].rs = 0;
    	RG int fx = Find(x);
    	Q.Del(t[rt[fx]].val);
    	if(x == rt[fx]) rt[fx] = tmp; t[x].val += d;
    	rt[fx] = Merge(rt[fx], x); t[rt[fx]].fa = 0;
    	Q.Push(t[rt[fx]].val);
    }
    
    IL void Query(RG int x){  Pushall(x); printf("%d
    ", t[x].val + add);  }
    
    int main(RG int argc, RG char* argv[]){
    	n = Read();
    	for(RG int i = 1; i <= n; ++i) t[i].val = Read(), Q.Push(t[i].val), fa[i] = rt[i] = i;
    	for(RG int m = Read(); m; --m){
    		RG char op[5]; RG int x, y, fx, fy;
    		scanf(" %s", op);
    		if(op[0] == 'U'){
    			x = Read(); y = Read(); fx = Find(x); fy = Find(y);
    			if(fx == fy) continue;
    			Q.Del(t[rt[fx]].val); Q.Del(t[rt[fy]].val);
    			fa[fx] = fy; rt[fy] = Merge(rt[fx], rt[fy]); t[rt[fy]].fa = 0;
    			Q.Push(t[rt[fy]].val);
    		}
    		else if(op[0] == 'A'){
    			if(op[1] == '1') x = Read(), y = Read(), Modify(x, y);
    			else if(op[1] == '2'){
    				x = Read(); y = Read(); fx = Find(x);
    				Q.Del(t[rt[fx]].val); Add(rt[fx], y); Q.Push(t[rt[fx]].val);
    			}
    			else x = Read(), add += x;
    		}
    		else{
    			if(op[1] == '1') x = Read(), Query(x);
    			else if(op[1] == '2') x = Read(), fx = Find(x), printf("%d
    ", t[rt[fx]].val + add);
    			else printf("%d
    ", Q.Top() + add);
    		}
    	}
        return 0;
    }
    
    
  • 相关阅读:
    Java实现批量下载《神秘的程序员》漫画
    mysql远程连接:ERROR 1130 (HY000): Host '*.*.*.*' is not allowed to connect to this MySQL server解决办法
    opencv学习_15 (利用cmake查看opencv的源码)
    jobs 命令
    中断子系统6_中断嵌套处理
    JPA一对多映射
    JPA Map映射
    JPA集合映射
    JPA删除实体
    JPA查找实体
  • 原文地址:https://www.cnblogs.com/cjoieryl/p/8277682.html
Copyright © 2011-2022 走看看