• LG P4146 序列终结者


    ( ext{Problem})

    支持区间加区间翻转区间最大值

    ( ext{Solution})

    ( ext{FHQ-Treap}) 两个标记加与翻转
    然后维护区间最大值

    ( ext{Code})

    #include <cstdio>
    #include <algorithm>
    #include <ctime>
    #define re register
    using namespace std;
    
    const int N = 5e4 + 5;
    int n, m, rt;
    int ls[N], rs[N], mx[N], val[N], siz[N], tag1[N], tag2[N], rnd[N];
    
    inline void read(int &x)
    {
    	x = 0; int f = 1; char ch = getchar();
    	while (ch < '0' || ch > '9') f = (ch == '-' ? -1 : f), ch = getchar();
    	while (ch >= '0' && ch <= '9') x = (x << 3) + (x << 1) + ch - '0', ch = getchar();
    	x *= f;
    }
    
    inline int new_node(int v)
    {
    	static int size = 0;
    	val[++size] = v, mx[size] = v, siz[size] = 1, rnd[size] = rand(),
    	ls[size] = rs[size] = tag1[size] = tag2[size] = 0;
    	return size;
    }
    
    inline void pushup(int p)
    {
    	siz[p] = siz[ls[p]] + siz[rs[p]] + 1, mx[p] = val[p];
    	if (ls[p]) mx[p] = max(mx[p], mx[ls[p]]);
    	if (rs[p]) mx[p] = max(mx[p], mx[rs[p]]);
    }
    
    inline void pushdown(int p)
    {
    	if (!p) return;
    	if (tag1[p])
    	{
    		if (ls[p]) tag1[ls[p]] += tag1[p], mx[ls[p]] += tag1[p], val[ls[p]] += tag1[p];
    		if (rs[p]) tag1[rs[p]] += tag1[p], mx[rs[p]] += tag1[p], val[rs[p]] += tag1[p]; 
    		tag1[p] = 0;
    	}
    	if (tag2[p])
    	{
    		tag2[p] = 0, swap(ls[p], rs[p]);
    		if (ls[p]) tag2[ls[p]] ^= 1;
    		if (rs[p]) tag2[rs[p]] ^= 1;
    	}
    }
    
    void split(int p, int k, int &x, int &y)
    {
    	if (!p) return void(x = y = 0);
    	pushdown(p);
    	if (k <= siz[ls[p]]) y = p, split(ls[p], k, x, ls[y]);
    	else x = p, split(rs[p], k - siz[ls[p]] - 1, rs[x], y);
    	pushup(p);
    }
    
    int merge(int x, int y)
    {
    	if (!x || !y) return x | y;
    	pushdown(x), pushdown(y);
    	if (rnd[x] < rnd[y]){rs[x] = merge(rs[x], y), pushup(x); return x;}
    	ls[y] = merge(x, ls[y]), pushup(y); return y;
    }
    
    int main()
    {
    	srand((unsigned)time(NULL));
    	read(n), read(m);
    	for(re int i = 1; i <= n; i++) rt = merge(rt, new_node(0));
    	for(re int i = 1, op, l, r, ad, x, y, u, v; i <= m; i++)
    	{
    		read(op), read(l), read(r);
    		split(rt, r, x, y), split(x, l - 1, u, v);
    		if (op == 1) read(ad), tag1[v] += ad, mx[v] += ad, val[v] += ad;
    		else if (op == 2) tag2[v] ^= 1;
    		else printf("%d
    ", mx[v]);
    		rt = merge(merge(u, v), y);
    	}
    }
    
  • 相关阅读:
    JavaScript——封装
    Vue.js——component(组件)
    MySQL数据库——安装教程(5.7版本)
    Vue.js——循环(Java、JSTL标签库、数据库)
    Vue.js——理解与创建使用
    JavaScript——闭包
    自定义最小索引优先队列
    自定义最大索引优先队列
    自定义最小优先队列
    自定义最大优先队列
  • 原文地址:https://www.cnblogs.com/leiyuanze/p/15041401.html
Copyright © 2020-2023  润新知