1. 程式人生 > >SP1557 GSS2 - Can you answer these queries II(線段樹)

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 }