bzoj 3745: [Coci2015]Norma

Posted ck666

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj 3745: [Coci2015]Norma相关的知识,希望对你有一定的参考价值。

Description

给定序列\(a_i\)

\[\sum_{i=1}^n \sum_{j=i}^n (j-i+1)\max\{a_i,a_{i+1}\cdots a_j\}\min\{a_i,a_{i+1}\cdots a_j\}\]

Input

第1行,一个整数N;
第2~n+1行,每行一个整数表示序列a。

Output

输出答案对10^9取模后的结果。

Sample Input

4
2 4 1 4
Sample Output

109

【数据范围】

\(N \le 500000\)
\(1 \le a_i \le 10^8\)


我还有什么话可以说呢,都是细节问题。细节什么的最讨厌了
维护前缀\(sum1,sum2,sum3\)分别是\([0]\)里记录前缀中每一个数的\(a_i*i\)后的和,\([1]\)里记录每一个数在区间里的前缀和,这样求一个区间的贡献可以表示成\(sum[i][0]-sum[i][1]*j\)

\(j\)是当前点的编号,于是这样玄学的复杂度>_<

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
using namespace std;
#define ll long long 
inline ll read(){
    ll an=0;
    char ch=getchar();
    while(ch<‘0‘||ch>‘9‘){ch=getchar();}
    while(‘0‘<=ch&&ch<=‘9‘){an=an*10+(ch^48);ch=getchar();}
    return an;
}
const ll mod=1e9;
const ll MAXn=500000+2333;
ll ans;
ll n;
ll sum1[MAXn][2],sum2[MAXn][2],sum3[MAXn][3],a[MAXn];
/*
\sum_{i=1}^n\sum_{j=i}^n(j-i+1)
\MAX\{a_i,a_{i+1}\cdots a_j\}
\MIN\{a_i,a_{i+1}\cdots a_j\}
*/
inline void prepare(){
    n=read();
    for(ll i=1;i<=n;i++)a[i]=read();
}
inline void solve(ll l,ll r){
    ll mid=l+r>>1;
    if(l==r){
        ans=(ans%mod+a[l]*a[l]%mod)%mod;
        return;
    }
    sum1[mid][0]=sum1[mid][1]=0;
    sum2[mid][0]=sum2[mid][1]=0;
    sum3[mid][0]=sum3[mid][1]=0;
    ll ma=-1,mi=1e9;
    for(ll i=mid+1;i<=r;i++){
        ma=max(ma,a[i]);
        mi=min(mi,a[i]);
        sum1[i][0]=ma%mod*mi%mod*i%mod;
        sum1[i][1]=ma*mi%mod;
        sum2[i][0]=mi*i%mod;sum2[i][1]=mi;
        sum3[i][0]=ma*i%mod;sum3[i][1]=ma;
        sum1[i][0]=(sum1[i][0]+sum1[i-1][0])%mod;
        sum1[i][1]=(sum1[i][1]+sum1[i-1][1])%mod;
        sum2[i][0]=(sum2[i][0]+sum2[i-1][0])%mod;
        sum2[i][1]=(sum2[i][1]+sum2[i-1][1])%mod;
        sum3[i][0]=(sum3[i][0]+sum3[i-1][0])%mod;
        sum3[i][1]=(sum3[i][1]+sum3[i-1][1])%mod;
    }
    ma=-1,mi=1e9;
    ll t1=a[mid+1],t2=a[mid+1];
    ll p1=mid,p2=mid;
    for(ll i=mid;i>=l;i--){
        ma=max(ma,a[i]);
        mi=min(a[i],mi);
        while(t1>=mi&&p1<r)p1++,t1=min(t1,a[p1+1]);
        while(t2<=ma&&p2<r)p2++,t2=max(t2,a[p2+1]);
        ll tmp;
        tmp=min(p1,p2);
        ll wi=(mid+2-i+tmp-i+1)*(tmp-mid)/2;
        ans=(ans+wi%mod*ma%mod*mi)%mod;
        tmp=max(p1,p2)+1;
        wi=sum1[r][0]-sum1[tmp-1][0];
        wi=(wi-(sum1[r][1]-sum1[tmp-1][1])%mod*(i-1))%mod;
        ans=(ans%mod+wi)%mod;
        if(p1<=p2){
            wi=(sum2[p2][0]-sum2[p1][0])%mod*ma%mod;
            wi=(wi-(sum2[p2][1]-sum2[p1][1])%mod*(i-1)%mod*ma+mod)%mod;
            ans=(ans+wi)%mod;
        }
        else{
            wi=(sum3[p1][0]-sum3[p2][0])%mod*mi;
            wi=(wi-(sum3[p1][1]-sum3[p2][1])%mod*(i-1)%mod*mi%mod+mod)%mod;
            ans=(ans+wi)%mod;
        }
    }
    solve(l,mid);
    solve(mid+1,r);
    ans=(ans%mod+mod)%mod;
}
int main(){
    prepare();
    solve(1,n);
    cout<<ans<<"\n";
    return 0;
}

以上是关于bzoj 3745: [Coci2015]Norma的主要内容,如果未能解决你的问题,请参考以下文章

bzoj3745 [Coci2015]Norma

bzoj3745: [Coci2015]Norma

bzoj 3745 [Coci2015]Norma——序列分治

bzoj 3745: [Coci2015]Norma

bzoj 3745: [Coci2015]Norma分治

题解-COCI-2015Norma