【题目分析】

线段树,好强!

首先从左往右依次扫描,线段树维护一下f[]。f[i]表示从i到当前位置的和的值。

然后询问按照右端点排序,扫到一个位置,就相当于查询区间历史最值。

关于历史最值问题:

标记是有顺序的,如果下方标记比较勤快,使得两个标记不会叠加,常数会很大,但是好写。

发现标记随着层数的递增越来越古老,(否则就被下放了),所以维护历史最大更新和当前更新即可。

好题!

【代码】

#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib> #include <map>
#include <set>
#include <queue>
#include <string>
#include <iostream>
#include <algorithm> using namespace std; #define maxn 1000005
#define inf 0x3f3f3f3f
#define F(i,j,k) for (int i=j;i<=k;++i)
#define D(i,j,k) for (int i=j;i>=k;--i) void Finout()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
freopen("wa.txt","w",stdout);
#endif
} int Getint()
{
int x=0,f=1; char ch=getchar();
while (ch<'0'||ch>'9') {if (ch=='-') f=-1; ch=getchar();}
while (ch>='0'&&ch<='9') {x=x*10+ch-'0'; ch=getchar();}
return x*f;
} const int buf=200005;
int n,m,a[maxn],last[maxn],bac[maxn];
struct Que{int l,r,id,ans;}q[maxn]; struct Segment_Tree{
int L,R,C;
int old_mx[maxn],old_lazy[maxn];
int now_mx[maxn],now_lazy[maxn];
void init()
{
memset(old_mx,0,sizeof old_mx);
memset(now_mx,0,sizeof now_mx);
memset(old_lazy,0,sizeof old_lazy);
memset(now_lazy,0,sizeof now_lazy);
}
void update(int o,int l,int r)
{
old_mx[o]=max(old_mx[o<<1],old_mx[o<<1|1]);
now_mx[o]=max(now_mx[o<<1],now_mx[o<<1|1]);
}
void pushdown(int o,int l,int r)
{
old_lazy[o<<1]=max(old_lazy[o<<1],now_lazy[o<<1]+old_lazy[o]);
old_lazy[o<<1|1]=max(old_lazy[o<<1|1],now_lazy[o<<1|1]+old_lazy[o]); old_mx[o<<1]=max(old_mx[o<<1],now_mx[o<<1]+old_lazy[o]);
old_mx[o<<1|1]=max(old_mx[o<<1|1],now_mx[o<<1|1]+old_lazy[o]); now_lazy[o<<1]+=now_lazy[o];
now_lazy[o<<1|1]+=now_lazy[o]; now_mx[o<<1]+=now_lazy[o];
now_mx[o<<1|1]+=now_lazy[o]; now_lazy[o]=old_lazy[o]=0;
}
void add(int o,int l,int r)
{
if (L<=l&&r<=R)
{
old_lazy[o]=max(old_lazy[o],now_lazy[o]+=C);
old_mx[o]=max(old_mx[o],now_mx[o]+=C);
return ;
}
pushdown(o,l,r);
int mid=l+r>>1;
if (R<=mid) add(o<<1,l,mid);
else if (L>mid) add(o<<1|1,mid+1,r);
else add(o<<1,l,mid),add(o<<1|1,mid+1,r);
update(o,l,r);
}
int query(int o,int l,int r)
{
if (L<=l&&r<=R) return old_mx[o];
pushdown(o,l,r);
int mid=l+r>>1;
if (R<=mid) return query(o<<1,l,mid);
if (L>mid) return query(o<<1|1,mid+1,r);
else return max(query(o<<1,l,mid),query(o<<1|1,mid+1,r));
}
}t; bool cmp1(Que x,Que y){return x.r<y.r;}
bool cmp2(Que x,Que y){return x.id<y.id;} int main()
{
Finout();
n=Getint();
F(i,1,n) a[i]=Getint();
F(i,1,n)
{
last[i]=bac[a[i]+buf];
bac[a[i]+buf]=i;
}
m=Getint();
F(i,1,m)
{
q[i].l=Getint();
q[i].r=Getint();
q[i].id=i;
}
sort(q+1,q+m+1,cmp1);
int h=0;
F(i,1,m)
{
while (h<q[i].r&&h<=n)
{
h++;
t.L=last[h]+1;
t.R=h;
t.C=a[h];
// printf("Add %d %d %d\n",t.L,t.R,t.C);
t.add(1,1,n);
}
t.L=q[i].l;t.R=q[i].r;
// printf("Query %d %d for %d\n",q[i].l,q[i].r,q[i].id);
q[i].ans=t.query(1,1,n);
}
sort(q+1,q+m+1,cmp2);
F(i,1,m) printf("%d\n",q[i].ans);
}

  

最新文章

  1. 活用shape、selector和layer-list来打造自己想要的背景效果
  2. 空的安卓工程添加activity
  3. 重置Oracle密码
  4. Fiddler-010-网络延时应用小技巧-模拟低网速环境
  5. js高级程序设计(六)面向对象
  6. Browser GetImage
  7. C#解析Json格式数据小结
  8. HDU2167+状态压缩DP
  9. 【转】Install MATLAB 2013a on CentOS 6.4 x64 with mode silent
  10. HDU1042(N!)题解
  11. python编写工具及配置(notepad++)
  12. oracle表连接------&amp;gt;排序合并连接(Merge Sort Join)
  13. 安卓的sqlite增删改
  14. BZOJ 3432: [Usaco2014 Jan]Cross Country Skiing (二分+染色法)
  15. cron任务解释
  16. SharePoint 2007 文档库中的文档添加评论功能
  17. Gym 100963B
  18. Tomcat connecttimeout sessiontimeout
  19. cython 成功创建import 模块
  20. Spark性能优化(2)——广播变量、本地缓存目录、RDD操作、数据倾斜

热门文章

  1. java 设计模式 之 桥梁模式
  2. MySQL存储引擎问题
  3. iphone开发设置默认字体
  4. make 与makefile(会不会写 makefile,从一个侧面说明了一个人是否具备完成大型工程的能力。)
  5. js 控制台输出
  6. 美国司法部解禁guns打印技术
  7. Java的jdbc调用SQL Server存储过程Bug201906131119
  8. iOS开发遇到的坑之三--使用asi框架在xcode下正常运行,但是打包时却不能进行网络访问
  9. ZJOI2018游记Round2
  10. Linux基础学习-使用Squid部署代理缓存服务