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

传送门

 

线段树好题

因为题目中相同的只算一次,我们可以联想到HH的项链,于是考虑离线的做法

先把所有的询问按$r$排序,然后每一次不断将$a[r]$加入线段树

线段树上维护四个值,$sum,hix,sumtag,hixtag$,分别代表当前节点的值,节点历史上的最大值,当前的增加标记,历史上最大的增加标记

然后pushdown的过程可以看代码,还是比较清楚的

考虑怎么添加元素,设序列中上一个与$i$相等的数的位置是$Pre[i]$,那么就把区间$[Pre[i],i]$加$a[i]$即可

查询的话只要查$[l,r]$的$hix$即可

除了pushdown有点烦其他都还好

 1 //minamoto
 2 #include<iostream>
 3 #include<cstdio>
 4 #include<algorithm>
 5 #define ls (p<<1)
 6 #define rs (p<<1|1)
 7 #define ll long long
 8 using namespace std;
 9 #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
10 char buf[1<<21],*p1=buf,*p2=buf;
11 template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
12 ll read(){
13     #define num ch-'0'
14     char ch;bool flag=0;ll res;
15     while(!isdigit(ch=getc()))
16     (ch=='-')&&(flag=true);
17     for(res=num;isdigit(ch=getc());res=res*10+num);
18     (flag)&&(res=-res);
19     #undef num
20     return res;
21 }
22 char sr[1<<21],z[20];int C=-1,Z;
23 inline void Ot(){fwrite(sr,1,C+1,stdout),C=-1;}
24 void print(ll x){
25     if(C>1<<20)Ot();if(x<0)sr[++C]=45,x=-x;
26     while(z[++Z]=x%10+48,x/=10);
27     while(sr[++C]=z[Z],--Z);sr[++C]='\n';
28 }
29 const int N=1e5+5;
30 struct node{
31     ll sum,hix,stag,htag;
32     node(){sum=hix=stag=htag=0;}
33     inline node operator +(node b){
34         node res;
35         res.sum=max(sum,b.sum),res.hix=max(hix,b.hix);
36         return res;
37     }
38 }b[N<<2];
39 struct Q{
40     int l,r,id;
41     inline bool operator <(const Q b)const
42     {return r<b.r;}
43 }q[N];
44 int n,m,cur[N*2],Pre[N],ql,qr;ll a[N],ans[N],k;
45 inline void upd(int p){b[p]=b[ls]+b[rs];}
46 void pd(int p){
47     b[ls].hix=max(b[ls].hix,b[ls].sum+b[p].htag);
48     b[rs].hix=max(b[rs].hix,b[rs].sum+b[p].htag);
49     b[ls].sum+=b[p].stag,b[rs].sum+=b[p].stag;
50     b[ls].htag=max(b[ls].htag,b[ls].stag+b[p].htag);
51     b[rs].htag=max(b[rs].htag,b[rs].stag+b[p].htag);
52     b[ls].stag+=b[p].stag,b[rs].stag+=b[p].stag;
53     b[p].stag=b[p].htag=0;
54 }
55 void update(int p,int l,int r){
56     if(ql<=l&&qr>=r){
57         b[p].sum+=k,cmax(b[p].hix,b[p].sum);
58         b[p].stag+=k,cmax(b[p].htag,b[p].stag);
59         return;
60     }
61     pd(p);int mid=(l+r)>>1;
62     if(ql<=mid) update(ls,l,mid);
63     if(qr>mid) update(rs,mid+1,r);
64     upd(p);
65 }
66 node query(int p,int l,int r){
67     if(ql<=l&&qr>=r) return b[p];
68     pd(p);int mid=(l+r)>>1;
69     if(ql>mid) return query(rs,mid+1,r);
70     else if(qr<=mid) return query(ls,l,mid);
71     else return query(ls,l,mid)+query(rs,mid+1,r);
72 }
73 int main(){
74 //    freopen("testdata.in","r",stdin);
75     n=read();
76     for(int i=1;i<=n;++i)
77     a[i]=read(),Pre[i]=cur[a[i]+(int)1e5],cur[a[i]+(int)1e5]=i;
78     m=read();
79     for(int i=1;i<=m;++i)
80     q[i].l=read(),q[i].r=read(),q[i].id=i;
81     sort(q+1,q+1+m);
82     for(int i=1,j=1;i<=n&&j<=m;++i){
83         ql=Pre[i]+1,qr=i,k=a[i];update(1,1,n);
84         for(;j<=m&&q[j].r<=i;++j){
85             ql=q[j].l,qr=q[j].r;
86             ans[q[j].id]=query(1,1,n).hix;
87         }
88     }
89     for(int i=1;i<=m;++i) print(ans[i]);
90     return Ot(),0;
91 }

 

posted @ 2018-10-21 19:17  bztMinamoto  阅读(264)  评论(1编辑  收藏  举报
Live2D