zoukankan      html  css  js  c++  java
  • [NOI2005] 维护数列

    前言

    这篇博客是 ( m FHQ Treap)

    说句闲话,研究平衡树的最好方法是:A了这道题,祝你们成功(滑稽

    题目

    洛谷

    DarkBZOJ

    讲解

    没什么好说的,只是过了这道题很爽,想水一下博客庆祝庆祝。

    所有操作都是模板,确实没什么好讲的,就讲几个细节吧。

    • 记得回收空间。

    • Reverse 操作的时候除了交换左右儿子,还要记得交换左右最大子段和。

    • 最大子段和不能为空集。

    • 更新最大子段和的时候很有可能会用到 (0) 号点,所以要把 (0) 号点与最大子段和相关的东西赋值为 (-infty)

    • 插入的时候先把插入的点建成一棵很平衡的树再插入,这样不开 (O2) 才能过。

    代码

    大常数代码
    //12252024832524
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #define TT template<typename T>
    using namespace std; 
    
    typedef long long LL;
    const int MAXN = 500005;
    const int MOD = 1e9 + 7;
    int n,m;
    char opt[10];
    
    LL Read()
    {
    	LL x = 0,f = 1;char c = getchar();
    	while(c > '9' || c < '0'){if(c == '-')f = -1;c = getchar();}
    	while(c >= '0' && c <= '9'){x = (x*10) + (c^48);c = getchar();}
    	return x * f;
    }
    TT void Put1(T x)
    {
    	if(x > 9) Put1(x/10);
    	putchar(x%10^48);
    }
    TT void Put(T x,char c = -1)
    {
    	if(x < 0) putchar('-'),x = -x;
    	Put1(x); if(c >= 0) putchar(c);
    }
    TT T Max(T x,T y){return x > y ? x : y;}
    TT T Min(T x,T y){return x < y ? x : y;}
    TT T Abs(T x){return x < 0 ? -x : x;}
    
    int rt;
    struct FHQ_Treap
    {
    	int l,r,val,siz,s,rd;//左右儿子、权值、siz、区间和、om value 
    	int lz1;//区间赋值标记 
    	int lz2;//翻转标记 
    	int lm,rm,ms;//左右及全局最大子段和
    }t[MAXN];
    int q[MAXN],tl = 500000;
    unsigned long long lst = 233;
    int Rand()
    {
    	lst *= 20050525;
    	lst += 520123;
    	return (int)(lst % MOD);
    }
    int newnode(int val)
    {
    	int ret = q[tl--];
    	if(t[ret].l) q[++tl] = t[ret].l;
    	if(t[ret].r) q[++tl] = t[ret].r;
    	t[ret].lz1 = MOD;
    	t[ret].lz2 = t[ret].l = t[ret].r = 0;
    	t[ret].siz = 1;
    	t[ret].lm = t[ret].rm = t[ret].ms = t[ret].s = t[ret].val = val;
    	t[ret].rd = Rand();
    	return ret;
    }
    void rev(int x)
    {
    	if(!x) return;
    	t[x].lz2 ^= 1;
    	swap(t[x].l,t[x].r);
    	swap(t[x].lm,t[x].rm);
    }
    void fuzhi(int x,int val)
    {
    	if(!x) return;
    	t[x].lz1 = val;
    	t[x].s = t[x].siz * val;
    	t[x].val = val;
    	t[x].lm = t[x].rm = t[x].ms = Max(val,t[x].s);
    }
    void down(int x)
    {
    	if(t[x].lz1^MOD) fuzhi(t[x].l,t[x].lz1),fuzhi(t[x].r,t[x].lz1),t[x].lz1 = MOD;
    	if(t[x].lz2) rev(t[x].l),rev(t[x].r),t[x].lz2 = 0;
    }
    void up(int x)
    {
    	t[x].siz = t[t[x].l].siz + t[t[x].r].siz + 1;
    	t[x].s = t[t[x].l].s + t[t[x].r].s + t[x].val;
    	t[x].lm = t[t[x].l].lm; t[x].lm = Max(t[x].lm,t[t[x].l].s + t[x].val + Max(0,t[t[x].r].lm));
    	t[x].rm = t[t[x].r].rm; t[x].rm = Max(t[x].rm,t[t[x].r].s + t[x].val + Max(0,t[t[x].l].rm));
    	t[x].ms = Max(t[t[x].l].ms,t[t[x].r].ms);
    	t[x].ms = Max(t[x].ms,Max(t[x].lm,t[x].rm));
    	t[x].ms = Max(t[x].ms,t[x].val+Max(0,t[t[x].l].rm)+Max(0,t[t[x].r].lm));
    }
    void split(int now,int val,int &x,int &y)
    {
    	if(!now) {x = y = 0;return;}
    	down(now);
    	if(t[t[now].l].siz+1 <= val)
    	{
    		x = now;
    		split(t[now].r,val-t[t[now].l].siz-1,t[now].r,y);
    	}
    	else
    	{
    		y = now;
    		split(t[now].l,val,x,t[now].l);
    	}
    	up(now); 
    }
    int mge(int x,int y)
    {
    	if(!x || !y) return x|y;
    	if(t[x].rd < t[y].rd)
    	{
    		down(x);
    		t[x].r = mge(t[x].r,y); up(x);
    		return x;
    	}
    	else
    	{
    		down(y);
    		t[y].l = mge(x,t[y].l); up(y);
    		return y;
    	}
    }
    void recycle(int x){q[++tl] = x;}
    int a[MAXN];
    int Build(int l,int r)
    {
    	if(l > r) return 0;
    	int mid = (l+r) >> 1;
    	int now = newnode(a[mid]);
    	t[now].l = Build(l,mid-1);
    	t[now].r = Build(mid+1,r);
    	up(now);
    	return now;
    }
    
    int main()
    {
    //	freopen("P2042_2.in","r",stdin);
    //	freopen("mine.out","w",stdout);
    	t[0].lm = t[0].rm = t[0].ms = -MOD;
    	for(int i = 1;i <= tl;++ i) q[i] = i;
    	n = Read(); m = Read();
    	for(int i = 1;i <= n;++ i) rt = mge(rt,newnode(Read()));
    	int x,y,z;
    	while(m --> 0)
    	{
    		scanf("%s",opt);
    		if(opt[0] == 'I')
    		{
    			int pos = Read(),len = Read();
    			split(rt,pos,x,y);
    			for(int i = 1;i <= len;++ i) a[i] = Read();
    			rt = mge(mge(x,Build(1,len)),y);
    		}
    		else if(opt[0] == 'D')
    		{
    			int pos = Read(),len = Read();
    			split(rt,pos-1,x,y);
    			split(y,len,y,z);
    			rt = mge(x,z);
    			recycle(y);
    		}
    		else if(opt[2] == 'K')
    		{
    			int pos = Read(),len = Read();
    			split(rt,pos-1,x,y);
    			split(y,len,y,z);
    			fuzhi(y,Read());
    			rt = mge(mge(x,y),z);
    		}
    		else if(opt[0] == 'R')
    		{
    			int pos = Read(),len = Read();
    			split(rt,pos-1,x,y);
    			split(y,len,y,z);
    			rev(y);
    			rt = mge(mge(x,y),z);
    		}
    		else if(opt[0] == 'G')
    		{
    			int pos = Read(),len = Read();
    			split(rt,pos-1,x,y);
    			split(y,len,y,z);
    			Put(t[y].s,'
    ');
    			rt = mge(mge(x,y),z);
    		}
    		else if(opt[2] == 'X') Put(t[rt].ms,'
    ');
    	}
    	return 0;
    }
    
  • 相关阅读:
    Debug入门之旅StackoverFlow exception的调试
    [软件调试学习笔记]WinDbg演示IA32 CPU下的Windows 分页机制下的地址转换过程
    转载推荐:COM中不同字符类型相互转换,例如char*, BSTR, CString等等
    一种强行指定dll assembly读取其相应*.dll.config配置文件的方法(又名:如何创建.net 的DCOM)
    COM中的error handling机制及示例(ISupportEfforInfo,ICreateErrorInfo,IErrorInfo)
    (转载)如何在WCF实现impersonnate客户端的功能
    如何实现DCOM或者COM+的远程调用
    [软件调试学习笔记]防止栈缓冲区溢出的基于Cookie的安全检查机制
    关于COM的RegFree(免注册)技术简介及实例讲解。
    如何通过扩展WCF来定制和扩展WCF行为
  • 原文地址:https://www.cnblogs.com/PPLPPL/p/15222277.html
Copyright © 2011-2022 走看看