zoukankan      html  css  js  c++  java
  • BZOJ4540: [Hnoi2016]序列

    4540: [Hnoi2016]序列

    Time Limit: 20 Sec  Memory Limit: 512 MB
    Submit: 1406  Solved: 659
    [Submit][Status][Discuss]

    Description

      给定长度为n的序列:a1,a2,…,an,记为a[1:n]。类似地,a[l:r](1≤l≤r≤N)是指序列:al,al+1,…,ar-
    1
    ,ar。若1≤l≤s≤t≤r≤n,则称a[s:t]是a[l:r]的子序列。现在有q个询问,每个询问给定两个数l和r,1≤l≤r
    ≤n,求a[l:r]的不同子序列的最小值之和。例如,给定序列5,2,4,1,3,询问给定的两个数为1和3,那么a[1:3]有
    6个子序列a[1:1],a[2:2],a[3:3],a[1:2],a[2:3],a[1:3],这6个子序列的最小值之和为5+2+4+2+2+2=17。

    Input

      输入文件的第一行包含两个整数n和q,分别代表序列长度和询问数。接下来一行,包含n个整数,以空格隔开
    ,第i个整数为ai,即序列第i个元素的值。接下来q行,每行包含两个整数l和r,代表一次询问。

    Output

      对于每次询问,输出一行,代表询问的答案。

    Sample Input

    5 5
    5 2 4 1 3
    1 5
    1 3
    2 4
    3 5
    2 5

    Sample Output

    28
    17
    11
    11
    17

    HINT

    1 ≤N,Q ≤ 100000,|Ai| ≤ 10^9

    思路{
      看到数据范围想到莫队。。。。。
      端点转移的话,基础的结论:对于一个当前区间$[l,r]$,新增端点$r+1$,产生新的$r-l+2$的区间,。
      这些某个端点固定,另外一个端点依次变化的一些区间,容易发现是这些区间的最小值在一段时间内连续不变。
      具体来说就是往那个方向所能延伸的最远长度,即$i$这个点到第一个小于它的数的位置。
      所以求出$L[i],R[i]$,$L[i]$为左边第一个小于它的数的位置,避免重复,$R[i]$为右边第一个小于等于它的数的位置。
      这个可以单调栈求出来。
      现在考虑端点移动。
      有了求的这个东西,我们发现当前区间$[l,r]$,新增端点$r+1$一定会向上述所说的那样算到$[l,r]$中值最小的位置。
      记录前缀和就可以快速求出新增端点到最小值的位置的贡献值.求这个位置倍增$ST$表
      设最小值位置$x$,$x$到另外一个端点$pos$,贡献$|x-pos|*a_x$.
      那么直接计算即可.
      有点卡常,把每个值的log,和$2^i$存起来,
    }
    #include<bits/stdc++.h>
    #define il inline
    #define RG register
    #define ll long long
    #define db double
    #define N 200010
    #define LL long long
    using namespace std;
    int n,m,a[N],L[N],R[N],st[N];
    ll sl[N],sr[N],l,r,ans,Ans[N],bas[N];
    int f[20][N],BL[N],Log[N];
    struct Query{
      int l,r,id;
      void read(int xx){id=xx;scanf("%d%d",&l,&r);}
    }q[N];
    bool comp(const Query & a,const Query & b){
      return BL[a.l]==BL[b.l]?a.r<b.r:BL[a.l]<BL[b.l];
    }
    void init(){
      bas[0]=1;for(int i=1;i<=19;++i)bas[i]=bas[i-1]<<1;
      scanf("%d%d",&n,&m);
      int len=sqrt(n);
      for(RG int i=1;i<=n;++i){scanf("%d",&a[i]),BL[i]=(i-1)/len+1,f[0][i]=i;}
      for(RG int i=2;i<=n;++i)Log[i]=Log[i>>1]+1;
      for(int i=1;(1<<i)<=n;++i)
        for(int j=1;j+(1<<i)-1<=n;++j)
          f[i][j]=(a[f[i-1][j]]<a[f[i-1][j+bas[i-1]]])?f[i-1][j]:f[i-1][j+bas[i-1]];
      for(RG int i=1;i<=n;++i){
        while(st[0]&&a[st[st[0]]]>=a[i])R[st[st[0]--]]=i;
        st[++st[0]]=i;
      }
      while(st[0])R[st[st[0]--]]=n+1;
      for(RG int i=n;i;i--){
        while(st[0]&&a[st[st[0]]]>a[i])L[st[st[0]--]]=i;
        st[++st[0]]=i;
      }
      while(st[0])L[st[st[0]--]]=0;
      for(RG int i=1;i<=n;++i)sl[i]=sl[L[i]]+1ll*(i-L[i])*a[i];
      for(RG int i=n;i;i--)sr[i]=sr[R[i]]+1ll*(R[i]-i)*a[i];
      for(RG int i=1;i<=m;++i)q[i].read(i);
      sort(q+1,q+m+1,comp);
    }
    int cal(){
      int x=l,y=r;
      if(x>y)swap(x,y);
      int c=Log[y-x+1];
      return a[f[c][x]]<a[f[c][y-bas[c]+1]]?f[c][x]:f[c][y-bas[c]+1];
    }
    void Modifyl(int delta){
      int x=cal();
      int ls=l,rs=r;if(ls>rs)swap(ls,rs);
      ans+=delta*((sr[ls]-sr[x])+1ll*a[x]*(rs-x+1));
    }
    void Modifyr(int delta){
      int x=cal();
      int ls=l,rs=r;if(ls>rs)swap(ls,rs);
      ans+=delta*((sl[rs]-sl[x])+1ll*a[x]*(x-ls+1));
    }
    void work(){
      l=1,r=1,ans=a[1];
      for(int i=1;i<=m;++i){
        if(r<q[i].r)for(;r!=q[i].r;r++,Modifyr(1));
        if(l<q[i].l)for(;l!=q[i].l;Modifyl(-1),l++);
        if(l>q[i].l)for(;l!=q[i].l;l--,Modifyl(1));
        if(r>q[i].r)for(;r!=q[i].r;Modifyr(-1),r--);
        Ans[q[i].id]=ans;
      }
      for(int i=1;i<=m;++i)cout<<Ans[i]<<"
    ";
    }
    int main(){
      init();
      work();
      return 0;
    }
    

      

      

  • 相关阅读:
    WPF 之 布局(一)
    CSS 之 内层div填充margin,外层div的背景色不会覆盖该margin
    T-SQL 之 多表联合更新
    jQuery
    Joomla, Wordpress, Drupal 全面详细Pk比较-转载
    js ==与===区别(两个等号与三个等号)
    Jquery DataTables 自定义布局sdom
    Jquery DataTable
    解决Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in
    firedebug调试Jquery
  • 原文地址:https://www.cnblogs.com/zzmmm/p/7502062.html
Copyright © 2011-2022 走看看