题解:

从没见过这么XXX的线段树啊。。。

T_T

我们考虑离线做,按1-n一个一个插入,并且维护区间【 j,i】(i为当前插入的数)j<i的最优值。

但这个最优值!!!

我们要保存历史的最优值,以及当前的最优值!!!还有lazy!!!也得分历史和现在!!T_T

怎么搞!!!

inline void update(int k,int z1,int z2)
{
t[k].tag[]=max(t[k].tag[],t[k].tag[]+z2);
t[k].tag[]+=z1;
t[k].mx[]=max(t[k].mx[],t[k].mx[]+z2);
t[k].mx[]+=z1;
t[k].mx[]=max(t[k].mx[],t[k].mx[]);
}
inline void pushdown(int k)
{
if(!t[k].tag[]&&!t[k].tag[])return;
update(k<<,t[k].tag[],t[k].tag[]);
update(k<<|,t[k].tag[],t[k].tag[]);
t[k].tag[]=t[k].tag[]=;
}

就是这么鬼畜,然后剩下的套模板就好了。。。

其实也蛮好理解的。

tag[0]表示从上次pushdown到现在加了多少

tag[1]表示从上次pushdown到现在tag[0]最多达到过多少,因为祖先的操作可能累计了很多次,我们只需要向下传一下最大的。

mx[0]和mx[1]与tag类似。

对拍了一组数据发现RE了,调了1h发现我dtmk写错了!!!说多了都是泪啊T_T

不过#2还是蛮开心的 哈哈~

代码:

 #include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<string>
#define inf 1000000000
#define maxn 200000+5
#define maxm 100000+5
#define eps 1e-10
#define ll long long
#define pa pair<int,int>
#define for0(i,n) for(int i=0;i<=(n);i++)
#define for1(i,n) for(int i=1;i<=(n);i++)
#define for2(i,x,y) for(int i=(x);i<=(y);i++)
#define for3(i,x,y) for(int i=(x);i>=(y);i--)
#define for4(i,x) for(int i=head[x],y=e[i].go;i;i=e[i].next,y=e[i].go)
#define mod 1000000007
using namespace std;
inline int read()
{
int x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=*x+ch-'';ch=getchar();}
return x*f;
}
int n,m,v[maxn],last[maxn],ans[maxn];
struct rec{int l,r,id;}a[maxn];
inline bool cmp(rec x,rec y){return x.r<y.r;}
struct seg{int l,r,mx[],tag[];}t[*maxn];
inline void build(int k,int l,int r)
{
t[k].l=l;t[k].r=r;int mid=(l+r)>>;
if(l==r)return;
build(k<<,l,mid);build(k<<|,mid+,r);
}
inline void update(int k,int z1,int z2)
{
t[k].tag[]=max(t[k].tag[],t[k].tag[]+z2);
t[k].tag[]+=z1;
t[k].mx[]=max(t[k].mx[],t[k].mx[]+z2);
t[k].mx[]+=z1;
t[k].mx[]=max(t[k].mx[],t[k].mx[]);
}
inline void pushup(int k)
{
for0(i,)t[k].mx[i]=max(t[k<<].mx[i],t[k<<|].mx[i]);
}
inline void pushdown(int k)
{
if(!t[k].tag[]&&!t[k].tag[])return;
update(k<<,t[k].tag[],t[k].tag[]);
update(k<<|,t[k].tag[],t[k].tag[]);
t[k].tag[]=t[k].tag[]=;
}
inline void add(int k,int x,int y,int z)
{
int l=t[k].l,r=t[k].r,mid=(l+r)>>;
if(l==x&&r==y){update(k,z,);return;}
pushdown(k);
if(y<=mid)add(k<<,x,y,z);
else if(x>mid)add(k<<|,x,y,z);
else add(k<<,x,mid,z),add(k<<|,mid+,y,z);
pushup(k);
}
inline int query(int k,int x,int y)
{
int l=t[k].l,r=t[k].r,mid=(l+r)>>;
if(l==x&&r==y)return t[k].mx[];
pushdown(k);
if(y<=mid)return query(k<<,x,y);
else if(x>mid)return query(k<<|,x,y);
else return max(query(k<<,x,mid),query(k<<|,mid+,y));
}
#define last(i) last[100000+i]
int main()
{
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
n=read();
for1(i,n)v[i]=read();
build(,,n);
m=read();
for1(i,m)a[i].l=read(),a[i].r=read(),a[i].id=i;
sort(a+,a+m+,cmp);
int j=;
for1(i,n)
{
int tmp=last(v[i]);last(v[i])=i;
add(,tmp+,i,v[i]);
while(a[j].r==i)ans[a[j].id]=query(,a[j].l,i),j++;
}
for1(i,m)printf("%d\n",ans[i]);
return ;
}

2482: [Spoj1557] Can you answer these queries II

Time Limit: 20 Sec  Memory Limit: 128 MB
Submit: 115  Solved: 67
[Submit][Status]

Description

给定n个元素的序列。 
给出m个询问:求l[i]~r[i]的最大子段和(可选空子段)。 
这个最大子段和有点特殊:一个数字在一段中出现了两次只算一次。 
比如:1,2,3,2,2,2出现了3次,但只算一次,于是这个序列的和是1+2+3=6。

Input

第一行一个数n。 
第二行n个数,为给定的序列,这些数的绝对值小于等于100000。 
第三行一个数m。 
接下来m行,每行两个数,l[i],r[i]。

Output

M行,每行一个数,为每个询问的答案。



Sample Input

9
4 -2 -2 3 -1 -4 2 2 -6
3
1 2
1 5
4 9

Sample Output

4
5
3

HINT

【数据说明】

30%:1 <= n, m <= 100

100%:1 <= n, m <= 100000

Source

BZOJ2482: [Spoj1557] Can you answer these queries II的更多相关文章

  1. 【BZOJ2482】[Spoj1557] Can you answer these queries II 线段树

    [BZOJ2482][Spoj1557] Can you answer these queries II Description 给定n个元素的序列. 给出m个询问:求l[i]~r[i]的最大子段和( ...

  2. [SPOJ1557] Can you answer these queries II

    [题目链接] https://www.lydsy.com/JudgeOnline/problem.php?id=2482 [算法] 线段树维护历史最值 时间复杂度 : O(NlogN) [代码] #i ...

  3. bzoj 2482: [Spoj GSS2] Can you answer these queries II 线段树

    2482: [Spoj1557] Can you answer these queries II Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 145 ...

  4. SPOJ 1557. Can you answer these queries II 线段树

    Can you answer these queries II Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 https://www.spoj.com/pr ...

  5. spoj gss2 : Can you answer these queries II 离线&&线段树

    1557. Can you answer these queries II Problem code: GSS2 Being a completist and a simplist, kid Yang ...

  6. SPOJ GSS2 - Can you answer these queries II(线段树 区间修改+区间查询)(后缀和)

    GSS2 - Can you answer these queries II #tree Being a completist and a simplist, kid Yang Zhe cannot ...

  7. SPOJ1557 GSS2 Can you answer these queries II 历史最值线段树

    传送门 题意:给出一个长度为$N$的数列,$Q$次询问,每一次询问$[l,r]$之间的最大子段和,相同的数只计算一次.所有数字的绝对值$\leq 10^5$ GSS系列中不板子的大火题,单独拿出来写 ...

  8. SPOJ GSS2 Can you answer these queries II

    Time Limit: 1000MS   Memory Limit: 1572864KB   64bit IO Format: %lld & %llu Description Being a ...

  9. GSS2-Can you answer these queries II

    ---恢复内容开始--- 这道题真的是非常恶心,看题解看了半天才弄懂,而且题解上说的相当简略. 此题大意是询问去掉重复元素的最大子区间和,没有修改操作. 没有修改操作,这样就可以离线处理了. 这道题有 ...

随机推荐

  1. 发现一个很好的android开发笔记库

    http://linux.linuxidc.com/ 密码和用户名都是www.linuxidc.com android基础教程到高手进阶,游戏开发,数据存储,android架构等.谢谢网站主分享!

  2. android手机推送视频到服务端

    项目需求,android手机向服务器推送视频.苦战几个星期终于实现,现记录下来以免以后忘记. 没做过Java,也没做过Android开发,只能现学现卖.在网上找了下搭建开发a  ndroid环境资料, ...

  3. 不用安装语言包,教你将PS界面语言修改成默认语言(英语)

    地址:http://www.cnblogs.com/Loonger/p/5112020.html 嗯,干脆利落,直接上教程.超简单的方法.(该方法可以随时在你已有语言[非英语]和PS默认语言[英语]之 ...

  4. 机器学习中的数学-矩阵奇异值分解(SVD)及其应用

    转自:http://www.cnblogs.com/LeftNotEasy/archive/2011/01/19/svd-and-applications.html 版权声明: 本文由LeftNotE ...

  5. BZOJ 3436: 小K的农场 差分约束

    题目链接: http://www.lydsy.com/JudgeOnline/problem.php?id=3436 题解: 裸的差分约束: 1.a>=b+c  ->  b<=a-c ...

  6. Unity手游:自动寻路Navmesh 跳跃 攀爬 斜坡

    原地址:http://dong2008hong.blog.163.com/blog/static/46968827201403114644210/ 步骤 1.在场景中摆放各种模型,包括地板,斜坡,山体 ...

  7. jsp自定义标签分析

    jsp自定义标签的优势体现在于jsp页面上面减少了java代码. jsp自定义标签有三大部分组成,首先是类继承TagSupport,实现doStartTag方法. public int doStart ...

  8. 关联式容器(associative containers)

    关联式容器(associative containers) 根据数据在容器中的排列特性,容器可分为序列式(sequence)和关联式(associative)两种. 标准的STL关联式容器分为set( ...

  9. java基础知识回顾之java集合类-Properties集合

    /** java.lang.Object   |--java.util.Dictionary<K,V>      |--java.util.Hashtable<Object,Obje ...

  10. java基础知识回顾之---java String final类构造方法

    /** * String 构造方法学习 *     String(byte[ ] bytes):通过byte数组构造字符串对象. *     String(byte[] bytes, int offs ...