SPOJ GSS2 Can you answer these queries II

Posted SilverNebula

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SPOJ GSS2 Can you answer these queries II相关的知识,希望对你有一定的参考价值。

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

Description

Being a completist and a simplist, kid Yang Zhe cannot solve but get Wrong Answer from most of the OI problems. And he refuse to write two program of same kind at all. So he always failes in contests.

When having a contest, Yang Zhe looks at the score of every problems first. For the problems of the same score, Yang Zhe will do only one of them. If he‘s lucky enough, he can get all the scores wanted.

Amber is going to hold a contest in SPOJ. She has made a list of N candidate problems, which fit Yang Zhe very well. So Yang Zhe can solve any problem he want. Amber lined up the problems, began to select. She will select a subsequence of the list as the final problems. Being A girl of great compassion, she‘d like to select such a subsequence (can be empty) that Yang Zhe will get the maximal score over all the possible subsequences.

Amber found the subsequence easily after a few minutes. To make things harder, Amber decided that, Yang Zhe can take this contest only if Yang Zhe can answer her Q questions. The question is: if the final problems are limited to be a subsequence of list[X..Y] (1 <= X <= Y <= N), what‘s the maximal possible score Yang Zhe can get?

As we know, Yang Zhe is a bit idiot (so why did he solve the problem with a negative score?), he got Wrong Answer again... Tell him the correct answer!

Input

  • Line 1: integer N (1 <= N <= 100000);
  • Line 2: N integers denoting the score of each problem, each of them is a integer in range [-100000, 100000];
  • Line 3: integer Q (1 <= Q <= 100000);
  • Line 3+i (1 <= i <= Q): two integers X and Y denoting the ith question.

Output

  • Line i: a single integer, the answer to the ith question.

Example

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

Output:
4
5
3

Warning: large input/output data,be careful with certain languages

Hint

Added by: Fudan University Problem Setters
Date: 2007-05-16
Time limit: 1s
Source limit: 50000B
Memory limit: 1536MB
Cluster: Cube (Intel G860)
Languages: All except: C99 strict ERL JS
Resource: Description, standard program and test data by Yang Zhe

 

这系列题没按难度顺序来啊……1~5里面感觉这道最难。

用线段树的叶子结点存a[i]表示序列的后缀和(即data[i]+data[i+1]+data[i+2]+...+data[n]),以及区间内最优答案。

离线处理,将询问按右端点从小到大排序。for i:=1 to n 从左往右不断将data[i]添加到线段树,并回答右端点等于i的询问(此时线段树里存的后缀和都只到i)。

如何排除重复数字?离散化数据,对每个数字记录上次出现的位置last,往线段树里添加新值时,只修改闭区间[last+1,i]

具体维护方法看代码:

  1 /*by SilverN*/
  2 #include<algorithm>
  3 #include<iostream>
  4 #include<cstring>
  5 #include<cstdio>
  6 #include<cmath>
  7 #define lc rt<<1
  8 #define rc rt<<1|1
  9 #define LL long long
 10 using namespace std;
 11 const int mxn=120010;
 12 int read(){
 13     int x=0,f=1;char ch=getchar();
 14     while(ch<0 || ch>9){if(ch==-)f=-1;ch=getchar();}
 15     while(ch>=0 && ch<=9){x=x*10+ch-0;ch=getchar();}
 16     return x*f;
 17 }
 18 int n,m;
 19 int data[mxn];
 20 int last[mxn<<2];//离散化 
 21 struct node{
 22     LL mx;//区间内最优解 
 23     LL prelazy,mksum;//标记 
 24     LL smm;//区间内最优的后缀和 
 25 }t[mxn<<2],tmp0;
 26 void push_up(int l,int r,int rt){
 27     t[rt].mx=max(t[lc].mx,t[rc].mx);
 28     t[rt].smm=max(t[lc].smm,t[rc].smm);
 29     return;
 30 }
 31 void pushdown(int l,int r,int rt){
 32     if(!t[rt].mksum && !t[rt].prelazy)return;
 33     int ls=rt<<1;int rs=rt<<1|1;
 34     //L
 35     t[ls].prelazy=max(t[ls].prelazy,t[ls].mksum+t[rt].prelazy);
 36     t[ls].mx=max(t[ls].mx,t[ls].smm+t[rt].prelazy);
 37     t[ls].mksum+=t[rt].mksum;
 38     t[ls].smm+=t[rt].mksum;    
 39     //R
 40     t[rs].prelazy=max(t[rs].prelazy,t[rs].mksum+t[rt].prelazy);
 41     t[rs].mx=max(t[rs].mx,t[rs].smm+t[rt].prelazy);
 42     t[rs].mksum+=t[rt].mksum;
 43     t[rs].smm+=t[rt].mksum;
 44     //
 45     t[rt].prelazy=t[rt].mksum=0;
 46     return;
 47 }
 48 void change(int L,int R,LL v,int l,int r,int rt){
 49     if(L<=l && r<=R){
 50         t[rt].smm+=v;//最优后缀和 
 51         t[rt].mksum+=v;//后缀和的增加量 
 52         t[rt].mx=max(t[rt].mx,t[rt].smm);//答案 
 53         t[rt].prelazy=max(t[rt].prelazy,t[rt].mksum);//答案的增加量 
 54         return;
 55     }
 56     int mid=(l+r)>>1;
 57     pushdown(l,r,rt);
 58     if(L<=mid)change(L,R,v,l,mid,lc);
 59     if(R>mid)change(L,R,v,mid+1,r,rc);
 60     push_up(l,r,rt);
 61     return;
 62 }
 63 LL query(int L,int R,int l,int r,int rt){
 64     if(L<=l && r<=R)return t[rt].mx;
 65     pushdown(l,r,rt);
 66     int mid=(l+r)>>1;
 67     LL res=-1e15;
 68     if(L<=mid)res=max(res,query(L,R,l,mid,lc));
 69     if(R>mid)res=max(res,query(L,R,mid+1,r,rc));
 70     return res;
 71 }
 72 struct qry{//存储询问 
 73     int l,r,id;
 74 }q[mxn];
 75 int cmp(qry a,qry b){
 76     return a.r<b.r;//按右端点从小到大排序 
 77 }
 78 LL ans[mxn];
 79 int bas=100001;
 80 int main(){
 81     n=read();
 82     int i,j,x,y,k;
 83     for(i=1;i<=n;i++)data[i]=read();
 84 //    Build(1,n,1);
 85     m=read();
 86     for(i=1;i<=m;i++){
 87         q[i].l=read();q[i].r=read();q[i].id=i;
 88     }
 89     sort(q+1,q+m+1,cmp);
 90     //
 91     int hd=1;//待处理询问 
 92     for(i=1;i<=n;i++){
 93         change(last[data[i]+bas]+1,i,data[i],1,n,1);
 94         last[data[i]+bas]=i;
 95         while(hd<=m && q[hd].r==i){
 96             ans[q[hd].id]=query(q[hd].l,q[hd].r,1,n,1);
 97             hd++;
 98         }
 99     }
100     for(i=1;i<=m;i++)
101         printf("%lld\n",ans[i]);
102     return 0;
103 }

 

以上是关于SPOJ GSS2 Can you answer these queries II的主要内容,如果未能解决你的问题,请参考以下文章

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

SPOJ - GSS2Can you answer these queries II(线段树)

SPOJ1557 GSS2 Can you answer these queries II 线段树

spoj GSS4 - Can you answer these queries IV

Spoj GSS3 - Can you answer these queries III

SPOJ GSS3 Can you answer these queries III