• SP1557 GSS2


    Link

    SP1557 GSS2 - Can you answer these queries II

    Solve

    正向处理很难,我们思考离线处理,每次加入A[i]离线统计答案,所以这个时候线段树上的一个节点(l)就表示([l,A[i]])这个区间的答案。

    这里x义x神仙已经将的很清楚了,补充一下,他用一个点来维护一段区间,是一种比较经典的做法。

    x义x的解释

    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    
    int N,M;
    int A[100005];
    int pre[2000005];
    
    struct node{
    	ll Max,HisMax,Lzy,HisLzy;
    	node operator +(const node b)const{
    		node c;c.Max=max(Max,b.Max);c.HisMax=max(HisMax,b.HisMax);
    		c.HisLzy=c.Lzy=0;
    		return c;
    	}
    }K[400005];
    
    void push_down(int x){
    	K[x<<1].HisMax=max(K[x<<1].HisMax,K[x<<1].Max+K[x].HisLzy);
    	K[x<<1].HisLzy=max(K[x<<1].HisLzy,K[x<<1].Lzy+K[x].HisLzy);
    	K[x<<1].Max+=K[x].Lzy;
    	K[x<<1].Lzy+=K[x].Lzy;
    	K[x<<1|1].HisMax=max(K[x<<1|1].HisMax,K[x<<1|1].Max+K[x].HisLzy);
    	K[x<<1|1].HisLzy=max(K[x<<1|1].HisLzy,K[x<<1|1].Lzy+K[x].HisLzy);
    	K[x<<1|1].Max+=K[x].Lzy;
    	K[x<<1|1].Lzy+=K[x].Lzy;
    	K[x].Lzy=K[x].HisLzy=0;
    }
    
    void Update(int x,int l,int r,int L,int R,ll k){
    	if(L<=l&&r<=R){
    		K[x].Max+=k;K[x].HisMax=max(K[x].HisMax,K[x].Max);
    		K[x].Lzy+=k;K[x].HisLzy=max(K[x].HisLzy,K[x].Lzy);
    		return;
    	}
    	push_down(x);
    	int mid=(l+r)>>1;
    	if(L<=mid) Update(x<<1,l,mid,L,R,k);
    	if(R>mid) Update(x<<1|1,mid+1,r,L,R,k);
    	K[x]=K[x<<1]+K[x<<1|1];
    	return;
    }
    
    node Query(int x,int l,int r,int L,int R){
    	if(L<=l&&r<=R) return K[x];
    	push_down(x);
    	int mid=(l+r)>>1;
    	if(R<=mid) return Query(x<<1,l,mid,L,R);
    	if(L>mid) return Query(x<<1|1,mid+1,r,L,R);
    	return Query(x<<1,l,mid,L,R)+Query(x<<1|1,mid+1,r,L,R);
    }
    
    int L[100005],R[100005],id[100005];
    node Ans[100005];
    bool cmp(int a,int b){
    	return R[a]<R[b];
    }
    
    int main(){
    	scanf("%d",&N);
    	for(int i=1;i<=N;i++) scanf("%d",&A[i]);
    	scanf("%d",&M);
    	for(int i=1;i<=M;i++) scanf("%d%d",&L[i],&R[i]),id[i]=i;
    	sort(id+1,id+M+1,cmp);
    	
    	int j=1;
    	for(int i=1;i<=N;i++){
    		Update(1,1,N,pre[A[i]+100000]+1,i,A[i]);
    		pre[A[i]+100000]=i;
    		while(R[id[j]]==i&&j<=M) Ans[id[j]]=Query(1,1,N,L[id[j]],R[id[j]]),j++;
    	}
    	for(int i=1;i<=M;i++) printf("%lld
    ",Ans[i].HisMax);
    	
    	return 0;
    }
    
    
  • 相关阅读:
    Tomcat配置JNDI
    (转)通过反编译深入理解Java String及intern
    (转)Java8内存模型-永久代(PermGen)和元空间(Metaspace)
    排序算法
    并发编程
    MySQL
    Go语言
    Go语言
    Go语言
    Go语言
  • 原文地址:https://www.cnblogs.com/martian148/p/13880549.html
Copyright © 2020-2023  润新知