• [HNOI2016]序列


    题目描述

    给定长度为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。

    输入输出格式

    输入格式:

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

    输出格式:

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

    输入输出样例

    输入样例#1:
    5 5
    5 2 4 1 3
    1 5
    1 3
    2 4
    3 5
    2 5
    输出样例#1:
    28 
    17 
    11 
    11 
    17

    说明

    1 <=N,Q <= 100000,|Ai| <= 10^9

    网上给出的大多是两种:莫队和线段树+矩阵

    可惜我这个菜鸡看不懂

    这里给出一种近似暴力的方法

    我们模仿影魔的线段树解法:

    离线,把询问按l从小到大

    R[i]表示i右边第一个比它小的位置

    显然子序列[i,i~R[i]-1]的答案都是a[i],维护一个线段树,给i~R[i]-1加上a[i]

    我们从n开始从后往前计算,当有询问左端点在i时

    求出1~右端点的和

    但是我们没有考虑i与R[i]之后的解,而且R[i]这样显然只会与在他后面形成子序列

    所以递归把子序列[i,R[i]~R[R[i]]-1].......都加上a[R[i]]

    但是这样如果碰到有序递减的序列会变成O(n^2logn)

    但是这种省选题数据大多是随机的,所以可以过

    有时间会补上莫队做法

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 using namespace std;
      6 struct Ask
      7 {
      8   int l;int r;int id;
      9 }ask[100001];
     10 long long c[800001],mark[800001],ans[200001],a[100001],aa[100001];
     11 int n,q,stack[100001],R[100001],flag;
     12 bool cmp(Ask a,Ask b)
     13 {
     14   return a.l<b.l;
     15 }
     16 void pushup(int rt)
     17 {
     18     c[rt]=c[rt*2]+c[rt*2+1];
     19 }
     20 void pushdown(int rt,int l,int r,int mid)
     21 {
     22     if (mark[rt])
     23     {
     24         mark[rt*2]+=mark[rt];
     25         mark[rt*2+1]+=mark[rt];
     26         c[rt*2]+=mark[rt]*(mid-l+1);
     27         c[rt*2+1]+=mark[rt]*(r-mid);
     28         mark[rt]=0;
     29     }
     30 }
     31 void change(int rt,int l,int r,int L,int R,long long d)
     32 {
     33     if (l>=L&&r<=R)
     34     {
     35         mark[rt]+=d;
     36         c[rt]+=(r-l+1)*d;
     37         return;
     38     }
     39     pushdown(rt,l,r,(l+r)/2);
     40     int mid=(l+r)/2;
     41     if (L<=mid) change(rt*2,l,mid,L,R,d);
     42     if (R>mid) change(rt*2+1,mid+1,r,L,R,d);
     43     pushup(rt); 
     44 }
     45 long long getsum(int rt,int l,int r,int L,int R)
     46 {
     47     if (l>=L&&r<=R)
     48     {
     49         return c[rt];
     50     }
     51     int mid=(l+r)/2;
     52     pushdown(rt,l,r,mid);
     53     long long s=0;
     54     if (L<=mid) s+=getsum(rt*2,l,mid,L,R);
     55     if (R>mid) s+=getsum(rt*2+1,mid+1,r,L,R);
     56     pushup(rt);
     57     return s;
     58 }
     59 void rev()
     60 {int i;
     61     for (i=1;i<=n;i++)
     62     aa[i]=a[n-i+1];
     63     for (i=1;i<=n;i++)
     64     a[i]=aa[i];
     65 }
     66 void zyys(int x)
     67 {
     68   while (x<=n-1)
     69     {
     70       int l=x,r=R[x]-1;
     71       change(1,1,n,l,r,a[l]);
     72       x=R[x];
     73     }
     74 }
     75 void work()
     76 {int top,i;
     77 memset(c,0,sizeof(c));
     78 memset(mark,0,sizeof(mark));
     79   sort(ask+1,ask+q+1,cmp);
     80   top=0,stack[top]=n+1;
     81   for (i=n;i>=1;i--)
     82     {
     83       while (top&&a[i]<a[stack[top]]) top--;
     84       R[i]=stack[top];
     85       stack[++top]=i;
     86     }
     87 n++;
     88 top=q;
     89 for (i=n;i>=1;i--)
     90   {
     91     zyys(i);
     92     while (top&&i==ask[top].l) ans[ask[top].id]+=getsum(1,1,n,1,ask[top].r),top--;
     93   }
     94 }
     95 int main()
     96 {int i;
     97   cin>>n>>q;
     98   for (i=1;i<=n;i++)
     99     {
    100       scanf("%lld",&a[i]);
    101     }
    102   for (i=1;i<=q;i++)
    103     {
    104       scanf("%d%d",&ask[i].l,&ask[i].r);
    105       ask[i].id=i;
    106     }
    107   work();
    108   for (i=1;i<=q;i++)
    109   printf("%lld
    ",ans[i]);
    110 }
  • 相关阅读:
    2018年5月份
    2018年4月份
    2018年3月份
    2018年2月份
    代码书写欣赏
    关于Model层中Datetime Datetime? 默认值的问题
    关于DotNetBar中DataGridViewX 自动全屏 Anchor属性无效问题
    关于ios 8 7 下的模态窗口大小的控制 代碼+場景(mainstoryboard)( Resizing UIModalPresentationFormSheet )
    ios 关于StoryBoard 的简易使用说明
    VS2012 Build相关
  • 原文地址:https://www.cnblogs.com/Y-E-T-I/p/7655517.html
Copyright © 2020-2023  润新知