zoukankan      html  css  js  c++  java
  • Jzoj5231 序列问题

    给你序列A,定义f(l,r)=max{al,al+1,....,ar} , g(l,r)=min{al,al+1,....,ar}

    求ΣΣf(i,j)*g(i,j) { i∈[1,n],j∈[i,n] }

    哇第一道cdq分治的题诶,当时好像还不会这个玩意2333

    我们cdq分治一下,先求出[1,mid]和[mid+1,r]的答案

    让后我们考虑枚举j∈[mid+1,r]

    对于每一个j,我们可以通过预处理出前缀min,max再二分出两个端点p1,p2满足

    f(p1,j)=g(p1,j)=A[j]

    f(p2,p1)=A[j]或者g(p2,p1)=A[j]

    最后f(l,p2)和g(l,p2)与A[j]无关

    每次统计答案可以分成这三个区间来维护

    又发现,由于A[j]的单调,p2和p1肯定是单调递减的,可以用指针来维护,成功将复杂度降为O(n lg n)

    #include<stdio.h>
    #include<algorithm>
    #define M 1000000007
    #define L long long
    using namespace std;
    L mx[500010],mn[500010];
    L sx[500010],s[500010];
    L sm[500010],sn[500010];
    int n;
    L cdq(int l,int r){
    	if(l==r) return s[l]*s[r]%M;
    	int m=l+r>>1,pi=m,pj=m;
    	L ans=(cdq(l,m)+cdq(m+1,r))%M;
    	mx[m+1]=-M; mn[m+1]=M; 
    	sm[m+1]=sn[m+1]=sx[m+1]=0;
    	for(int i=m;i>=l;--i){
    		mx[i]=max(mx[i+1],s[i]);
    		mn[i]=min(mn[i+1],s[i]);
    		sm[i]=(sm[i+1]+mx[i])%M;
    		sn[i]=(sn[i+1]+mn[i])%M;
    		sx[i]=(sx[i+1]+mx[i]*mn[i]%M)%M;
    	}
    	L rm=-M,rn=M;
    	for(int j=m+1;j<=r;++j){
    		rm=max(s[j],rm);
    		rn=min(s[j],rn);
    		while(pi>=l&&mx[pi]<rm) pi--;
    		while(pj>=l&&mn[pj]>rn) pj--;
    		if(pi>pj){
    			ans=(ans+(m-pi)*rm%M*rn%M)%M;
    			ans=(ans+rn%M*(sm[pj+1]-sm[pi+1])%M)%M;
    			ans=(ans+sx[l]-sx[pj+1]+M)%M;
    		} else {
    			ans=(ans+(m-pj)*rm%M*rn%M)%M;
    			ans=(ans+rm*(sn[pi+1]-sn[pj+1])%M)%M;
    			ans=(ans+sx[l]-sx[pi+1]+M)%M;
    		}
    	}
    	return ans;
    }
    int main(){
    	freopen("seq.in","r",stdin);
    	freopen("seq.out","w",stdout);
    	scanf("%d",&n);
    	for(int i=1;i<=n;++i) scanf("%lld",s+i);
    	printf("%lld
    ",(M+cdq(1,n))%M);
    }

  • 相关阅读:
    项目总结1--技术
    基于MFC的Opengl实现动画
    vs2010 MFC Opengl实现
    设计模式-状态模式
    设计模式-访问者模式
    设计模式-责任链模式
    设计模式-中介者模式
    设计模式-命令模式
    设计模式-备忘录模式
    设计模式-观察者模式
  • 原文地址:https://www.cnblogs.com/Extended-Ash/p/7846021.html
Copyright © 2011-2022 走看看