zoukankan      html  css  js  c++  java
  • Luogu P3273 [SCOI2011]棘手的操作(左偏树)

    什么恶心东西啊,又水又烦
    两个可并堆维护即可

    #include <cstdio>
    #include <iostream>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #define R(a,b,c) for(register int a = (b); (a) <= (c); ++(a))
    #define nR(a,b,c) for(register int a = (b); (a) >= (c); --(a))
    #define Fill(a,b) memset(a, b, sizeof(a))
    #define Swap(a,b) ((a) ^= (b) ^= (a) ^= (b))
    #define ll long long
    #define u32 unsigned int
    #define u64 unsigned long long
     
    #define ON_DEBUGG
     
    #ifdef ON_DEBUGG
     
    #define D_e_Line printf("
    ----------
    ")
    #define D_e(x) cout << (#x) << " : " << x << endl
    #define Pause() system("pause")
    #define FileOpen() freopen("in.txt", "r", stdin)
    #define FileSave() freopen("out.txt", "w", stdout)
    #include <ctime>
    #define TIME() fprintf(stderr, "
    time: %.3fms
    ", clock() * 1000.0 / CLOCKS_PER_SEC)
    
    #else
     
    #define D_e_Line ;
    #define D_e(x) ;
    #define Pause() ;
    #define FileOpen() ;
    #define FileSave() ;
    #define TIME() ;
    //char buf[1 << 21], *p1 = buf, *p2 = buf;
    //#define getchar() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++)
     
    #endif
     
    using namespace std;
    struct ios{
        template<typename ATP>inline ios& operator >> (ATP &x){
            x = 0; int f = 1; char ch;
            for(ch = getchar(); ch < '0' || ch > '9'; ch = getchar()) if(ch == '-') f = -1;
            while(ch >= '0' && ch <= '9') x = x * 10 + (ch ^ '0'), ch = getchar();
            x *= f;
            return *this;
        }
    }io;
     
    template<typename ATP>inline ATP Max(ATP a, ATP b){
        return a > b ? a : b;
    }
    template<typename ATP>inline ATP Min(ATP a, ATP b){
        return a < b ? a : b;
    }
    template<typename ATP>inline ATP Abs(ATP a){
        return a < 0 ? -a : a;
    }
    
    const int N = 3e5 + 7;
    
    #define int long long
    int n, tagAll, root;
    
    #define ls ch[x][0]
    #define rs ch[x][1]
    
    int a[N];
    struct LeftTree{
    	int ch[N][2], val[N], tag[N], fa[N], dis[N];
    	
    	inline void Clear(int x) {
    		ch[x][0] = ch[x][1] = fa[x] = 0;
    	}
    	
    	inline int Sum(int x) {
    		int sum = 0;
    		for(x = fa[x]; x; x = fa[x]) sum += tag[x];
    		return sum;
    	}
    	
    	inline void Pushdown(int x) {
    		if(!tag[x]) return;
    		if(ls) val[ls] += tag[x], tag[ls] += tag[x];
    		if(rs) val[rs] += tag[x], tag[rs] += tag[x];
    		tag[x] = 0;
    	}
    	
    	inline int Merge(int x, int y) {
    		if(!x || !y) return x | y;
    		if(val[x] < val[y]) Swap(x, y);
    		Pushdown(x);
    		rs = Merge(rs, y);
    		fa[ls] = fa[rs] = x;
    		if(dis[rs] > dis[ls]) Swap(ls, rs);
    		dis[x] = dis[rs] + 1;
    		return x;
    	}
    	
    	inline int Find(int x) {
    		while(fa[x]) x = fa[x];
    		return x;
    	}
    	
    	inline int Del(int x) {
    		Pushdown(x);
    		int father = fa[x];
    		int rt = Merge(ls, rs);
    		fa[rt] = father;
    		if(father) ch[father][x == ch[father][1]] = rt;
    		while(father){
    			if(dis[ch[father][0]] < dis[ch[father][1]])
    				Swap(ch[father][0], ch[father][1]);
    			if(dis[father] == dis[ch[father][1]] + 1)
    			 	return root;
    			dis[father] = dis[ch[father][1]] + 1;
    			rt = father;
    			father = fa[father];
    		}
    		return rt;
    	}
    	
    	inline int Push(int x, int w) {
    		int father = Find(x);
    		if(father == x){
    			if(!ls && !rs){
    				val[x] += w;
    				return x;
    			}
    			else{
    				if(ls)
    					father = ls;
    				else
    					father = rs;
    			}
    		}
    		Del(x);
    		val[x] += w + Sum(x);
    		Clear(x);
    		return Merge(Find(father), x);
    	}
    	
    	int q[N];
    	inline int Build() {
    		int h = 0, t = 0;
    		R(i,1,n){
    			q[++t] = i;
    		}
    		while(h != t){
    			int x = q[++h];
    			if(h == N - 5) h = 0;
    			int y = q[++h];
    			if(h == N - 5) h = 0;
    			q[++t] = Merge(x, y);
    			if(t == N - 5) t = 0;
    		}
    		return q[t];
    	}
    }T, H;
    
    #undef int
    int main() {
    #define int long long
    //FileOpen();
    	io >> n;
    	T.dis[0] = H.dis[0] = -1;
    	R(i,1,n){
    		io >> a[i];
    		T.val[i] = H.val[i] = a[i];
    	}	
    	root = H.Build();
    	int m;
    	io >> m;
    	char opt[7];
    	while(m--){
    		scanf("%s", opt + 1);
    		if(opt[1] == 'U'){
    			int x, y;
    			io >> x >> y;
    			x = T.Find(x), y = T.Find(y);
    			if(x == y) continue;
    			int tmp = T.Merge(x, y);
    			if(tmp == x)
    				root = H.Del(y);
    			else
    				root = H.Del(x);
    		}
    		else if(opt[1] == 'A' && opt[2] == '1'){
    			int x, w;
    			io >> x >> w;
    			root = H.Del(T.Find(x));
    			int tmp = T.Push(x, w);
    			H.val[tmp] = T.val[tmp];
    			H.Clear(tmp);
    			root = H.Merge(root, tmp);
    		}
    		else if(opt[1] == 'A' && opt[2] == '2'){
    			int x, w;
    			io >> x >> w;
    			int father = T.Find(x);
    			root = H.Del(father);
    			T.val[father] += w;
    			T.tag[father] += w;
    			H.val[father] = T.val[father];
    			H.Clear(father);
    			root = H.Merge(root, father);
    		}
    		else if(opt[1] == 'A' && opt[2] == '3'){
    			int w;
    			io >> w;
    			tagAll += w;
    		}
    		else if(opt[1] == 'F' && opt[2] == '1'){
    			int x;
    			io >> x;
    			printf("%lld
    ", T.val[x] + tagAll + T.Sum(x));
    		}
    		else if(opt[1] == 'F' && opt[2] == '2'){
    			int x;
    			io >> x;
    			printf("%lld
    ", T.val[T.Find(x)] + tagAll);
    		}
    		else{
    			printf("%lld
    ", H.val[root] + tagAll);
    		}
    	}
    	
    	return 0;
    }
    
  • 相关阅读:
    还在使用golang 的map 做Json编码么?
    Golang 性能测试(2) 性能分析
    golang 性能测试 (1) 基准性能测试
    消息队列 NSQ 源码学习笔记 (五)
    消息队列 NSQ 源码学习笔记 (四)
    消息队列 NSQ 源码学习笔记 (三)
    消息队列 NSQ 源码学习笔记 (二)
    消息队列 NSQ 源码学习笔记 (一)
    你不知道的空格
    Supervisor 使用和进阶4 (Event 的使用)
  • 原文地址:https://www.cnblogs.com/bingoyes/p/11653717.html
Copyright © 2011-2022 走看看