题解:

从没见过这么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. c++ 时间格式化

    struct tm tm_time; strptime(time.c_str(), "%Y%m%d %H:%M:%S", &tm_time); time_t tt = mk ...

  2. 'mysql' 不是内部或外部命令,也不是可运行的程序或批处理文件的解决办法

    前言: 本文的解决方法来自http://www.cnblogs.com/xionghui/archive/2012/04/11/2442404.html --感谢! 问题描述:新电脑装mysql后在c ...

  3. find查找指定类型文件并删除

            问题描述:                      查找当前目录下指定类型的文件              问题解决:                     (1)find命令   ...

  4. linux进程管理之服务

     init进程首先通过initable查看运行级别,然后运行rc.d下面的sysinit,然后调用rc,然后运行rc###连接到init.d下面的服务.自启动. chkconfig命令只是查看和设置服 ...

  5. 【BZOJ】【2982】Combination

    排列组合 Lucas定理模板题…… 感觉我做题顺序有点问题啊……应该是BZOJ 2982-->HDOJ 3037-->BZOJ 1272 好吧这个现在来看就有些水了…… 预处理一下fact ...

  6. PHP之cookie相关实例教程与经典代码

    ·php 中cookie和session的用法比较 ·php会话控制cookie与Session会话处理 ·php中利用cookie实现购物车实例 ·php中cookie与session应用学习笔记 ...

  7. linux 下 apache启动、停止、重启命令

    基本的操作方法: 本文假设你的apahce安装目录为/usr/local/apache2,这些方法适合任何情况 apahce启动命令: 推荐/usr/local/apache2/bin/apachec ...

  8. Root resource classes

    Overview A root resource class is the entry point into a JAX-RS implemented RESTful Web service. It ...

  9. POJ 1504 Adding Reversed Numbers (水题,高精度整数加法)

    题意:给两个整数,求这两个数的反向数的和的反向数,和的末尾若为0,反向后则舍去即可.即若1200,反向数为21.题目给出的数据的末尾不会出现0,但是他们的和的末尾可能会出现0. #include &l ...

  10. ubantu安装jdk来配置hadoop

    1.将jdk-7u5-linux-x64.tar.gz拷贝到/usr/lib/jdk/目录下面,这里如果没有jdk文件夹,则创建该文件夹,命令: sudo mkdir jdk //创建文件夹jdk s ...