• SP1557 GSS2 Can you answer these queries II(离线 线段树)


    SP1557 GSS2 - Can you answer these queries II

    \(\bigstar\texttt{Hint}\):遇到去重的问题,我们通常考虑离线询问后处理。

    可以枚举右端点,将询问存储在右端点,考虑用数据结构记录左端点的信息。

    那么我们如果用线段树维护左端点为它时的答案,需要维护一下几种信息:

    • 历史最大值 \(hismax\)
    • 下传标记的增加值 \(lazadd\)
    • 当前的区间最大值 \(maxx\)

    WA 了捏,啊标记没有及时下传,可能有中间过程中的最大值没有统计到。

    那就再记下一个 tag 表示历史最大 \(lazaddmax\)\(lazadd\) 取最大值。

    #define Maxn 400005
    int n,m;
    int a[Maxn],pre[Maxn<<1];
    ll ans[Maxn];
    vector<pa> q[Maxn];
    /*
    由于下面标价下传时变量名称容易引起误导,下次写的时候不妨这样写:
    struct TREE
    {
    	// All=pushed+unpushed
    	ll maxAll,All,maxUnpused,Unpushed
    	TREE(int _maxAll=0,int _All=0,int _maxUnpushed=0,int _Unpushed=0):
    		maxAll(_maxAll),All(_All),
    		maxUnpushed(_maxUnpushed),Unpushed(_Unpushed){}
    	inline void Push(ll New,ll maxNew)
    	{
    		maxAll=max(maxAll,All+maxNew);
    		All+=New;
    		maxUnpushed=max(maxUnpushed,maxNew);
    		Unpushed+=New;
    	}
    }tree[Maxn<<2];
    */
    struct TREE
    {
    	ll hismax,lazadd,maxx,lazaddmax;
    	TREE(int H=0,int La=0,int M=0,int Lam=0):
    		hismax(H),lazadd(La),maxx(M),lazaddmax(Lam){}
    	inline void Push(ll x,ll addmax)
    	{
    		lazaddmax=max(lazaddmax,lazadd+addmax);
    		lazadd+=x;
    		hismax=max(hismax,maxx+addmax);
    		maxx+=x;
    	}
    }tree[Maxn<<2];
    inline void pushdown(int p)
    {
    	tree[p<<1].Push(tree[p].lazadd,tree[p].lazaddmax);
    	tree[p<<1|1].Push(tree[p].lazadd,tree[p].lazaddmax);
    	tree[p].lazadd=tree[p].lazaddmax=0;
    }
    inline void pushup(int p)
    {
    	tree[p].maxx=max(tree[p<<1].maxx,tree[p<<1|1].maxx);
    	tree[p].hismax=max(tree[p].hismax,tree[p].maxx);
    }
    void add(int p,int nl,int nr,int l,int r,ll x)
    {
    	if(nl>=l && nr<=r) { tree[p].Push(x,x); return; }
    	pushdown(p);
    	int mid=(nl+nr)>>1;
    	if(mid>=l) add(p<<1,nl,mid,l,r,x);
    	if(mid<r) add(p<<1|1,mid+1,nr,l,r,x);
    	pushup(p);
    }
    ll query(int p,int nl,int nr,int l,int r)
    {
    	if(nl>=l && nr<=r) return tree[p].hismax;
    	pushdown(p);
    	int mid=(nl+nr)>>1; ll ret=0;
    	if(mid>=l) ret=max(ret,query(p<<1,nl,mid,l,r));
    	if(mid<r) ret=max(ret,query(p<<1|1,mid+1,nr,l,r));
    	pushup(p);
    	return ret;
    }
    int main()
    {
    	n=rd();
    	for(int i=1;i<=n;i++) a[i]=rd();
    	m=rd();
    	for(int i=1,l,r;i<=m;i++) l=rd(),r=rd(),q[r].eb(l,i);
    	for(int r=1;r<=n;r++)
    	// attention !! a_i\in[-100000,100000]
    	{
    		int Last=pre[a[r]+100000];
    		add(1,1,n,Last+1,r,a[r]),pre[a[r]+100000]=r;
    		for(pa v:q[r]) ans[v.se]=query(1,1,n,v.fi,r);
    	}
    	for(int i=1;i<=m;i++) printf("%lld\n",ans[i]);
    	return 0;
    }
    
  • 相关阅读:
    Windows下分布式缓存Memcached参数帮助文档
    十条不错的编程观点
    转载志凡:网站技术分析报告之——开心网(kaixin.com)
    转载:由图片SEO想起
    Memcache基础教程
    【C#学习笔记】构造函数重载,构造函数相互调用,静态构造函数
    【C#学习笔记】单精度和双精度浮点型操作留意。
    VB进行子类化
    通过 Apache 配置 Rewrite 支持 .htaccess
    【C#学习笔记】各种定义方法的例子
  • 原文地址:https://www.cnblogs.com/EricQian/p/16585849.html
Copyright © 2020-2023  润新知