• 洛谷P3246 [HNOI2016]序列


    传送门

    题解

     1 //minamoto
     2 #include<iostream>
     3 #include<cstdio>
     4 #define ll long long
     5 using namespace std;
     6 #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
     7 char buf[1<<21],*p1=buf,*p2=buf;
     8 int read(){
     9     #define num ch-'0'
    10     char ch;bool flag=0;int res;
    11     while(!isdigit(ch=getc()))
    12     (ch=='-')&&(flag=true);
    13     for(res=num;isdigit(ch=getc());res=res*10+num);
    14     (flag)&&(res=-res);
    15     #undef num
    16     return res;
    17 }
    18 char sr[1<<21],z[20];int C=-1,Z;
    19 inline void Ot(){fwrite(sr,1,C+1,stdout),C=-1;}
    20 void print(ll x){
    21     if(C>1<<20)Ot();if(x<0)sr[++C]=45,x=-x;
    22     while(z[++Z]=x%10+48,x/=10);
    23     while(sr[++C]=z[Z],--Z);sr[++C]='
    ';
    24 }
    25 const int N=1e5+5,inf=0x3f3f3f3f;
    26 int n,m,top,bin[17],f[N][17],a[N],Pre[N],suf[N],s[N],log[N];ll fl[N],fr[N],gl[N],gr[N];
    27 inline int cmp(int x,int y){return a[x]<a[y]?x:y;}
    28 inline int query(int l,int r){int k=log[r-l+1];return cmp(f[l][k],f[r-bin[k]+1][k]);}
    29 int main(){
    30 //    freopen("testdata.in","r",stdin);
    31     n=read(),m=read(),a[n+1]=a[0]=inf;
    32     bin[0]=1;for(int i=1;i<=16;++i) bin[i]=bin[i-1]<<1;
    33     for(int i=2;i<=n;++i) log[i]=log[i>>1]+1;
    34     for(int i=1;i<=n;++i) a[i]=read(),f[i][0]=i;
    35     for(int j=1;j<=log[n];++j) for(int i=1;i<=n-bin[j-1]+1;++i)
    36     f[i][j]=cmp(f[i][j-1],f[i+bin[j-1]][j-1]);
    37     for(int i=1;i<=n;++i){
    38         while(top&&a[s[top]]>a[i]) suf[s[top--]]=i;
    39         Pre[i]=s[top],s[++top]=i;
    40     }while(top) Pre[s[top]]=s[top-1],suf[s[top--]]=n+1;
    41     for(int i=1;i<=n;++i) fr[i]=(ll)a[i]*(i-Pre[i])+fr[Pre[i]],gr[i]=gr[i-1]+fr[i];
    42     for(int i=n;i;--i) fl[i]=(ll)a[i]*(suf[i]-i)+fl[suf[i]],gl[i]=gl[i+1]+fl[i];
    43     while(m--){
    44         int l=read(),r=read(),p=query(l,r);
    45         print((ll)(p-l+1)*(r-p+1)*a[p]+
    46             gr[r]-gr[p]-fr[p]*(r-p)+
    47             gl[l]-gl[p]-fl[p]*(p-l));
    48     }
    49     return Ot(),0;
    50 }
  • 相关阅读:
    合并两个有序数组
    删除排序数组中的重复项 II
    对称二叉树
    相同的树
    二叉树的最大深度
    从前序与中序遍历序列构造二叉树
    vue简单案例_动态添加删除用户数据
    对vue的初步学习(一)
    关于java for循环常见练习题
    关于java中循环的学习
  • 原文地址:https://www.cnblogs.com/bztMinamoto/p/9823082.html
Copyright © 2020-2023  润新知