zoukankan      html  css  js  c++  java
  • [hdu6989]Didn't I Say to Make My Abilities Average in the Next Life?!

    显然问题即求$frac{sum_{xle lle rle y}(max_{lle ile r}a_{i}+min_{lle ile r}a_{i})}{(y-x+2)(y-x+1)}$

    分母显然是常数,分子中$max$​和$min$​是类似地,不妨仅考虑$sum_{xle lle rle y}max_{lle ile r}a_{i}$

    将询问离线,不断增大右端点$r$​,并维护$ans_{i}=sum_{r'=i}^{r}max_{ile jle r'}a_{j}$​​,那么即对$ans_{i}$​​区间求和

    将$ans_{i}$​​​写作$rcdot max_{i}-sum_{i}$​​​的形式(其中$max_{i}=max_{ile jle r}a_{j}$​),显然可以对两者分别求和​​

    下面,考虑从$r-1$​变为$r$​对$(max_{i},sum_{i})$​的影响:

    维护一个单调栈(从栈底到栈顶单调递减),假设弹出栈顶元素$x$​​​​​​​,且下一个元素为$y$​​​​​​(若栈为空则$y=0$​​​​​),那么即对区间$(y,x]$​​​​的$max_{i}$​​​​增加$a_{r}-a_{x}$​​​​,$sum_{i}$​​​​增加$(r-1)(a_{r}-a_{x})$​​​​

    另外还要维护$r$​​​​​​的答案,即令$(max_{r},sum_{r})=(a_{r},(r-1)a_{r})$​​​​​​

    即要支持区间加和区间查询,使用线段树即可,复杂度为$o(nlog n)$​,可以通过

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define N 200005
     4 #define mod 1000000007
     5 #define ll long long
     6 #define pii pair<int,int>
     7 #define mp make_pair
     8 #define fi first
     9 #define se second
    10 #define L (k<<1)
    11 #define R (L+1)
    12 #define mid (l+r>>1)
    13 struct Data{
    14     int l,r,id;
    15     bool operator < (const Data &k)const{
    16         return r<k.r;
    17     }
    18 }q[N];
    19 int t,n,m,inv[N],a[N],mn[N],mx[N],ans[N];
    20 pii tag[N<<2],f[N<<2];
    21 pii merge(pii x,pii y){
    22     return mp((x.fi+y.fi)%mod,(x.se+y.se)%mod);
    23 }
    24 void upd(int k,int l,int r,pii o){
    25     int len=r-l+1;
    26     tag[k]=merge(tag[k],o);
    27     f[k]=merge(f[k],mp((ll)len*o.fi%mod,(ll)len*o.se%mod));
    28 }
    29 void down(int k,int l,int r){
    30     upd(L,l,mid,tag[k]);
    31     upd(R,mid+1,r,tag[k]);
    32     tag[k]=mp(0,0);
    33 }
    34 void build(int k,int l,int r){
    35     f[k]=mp(0,0);
    36     if (l==r)return;
    37     build(L,l,mid);
    38     build(R,mid+1,r);
    39 }
    40 void update(int k,int l,int r,int x,int y,pii z){
    41     if ((l>y)||(x>r))return;
    42     if ((x<=l)&&(r<=y)){
    43         upd(k,l,r,z);
    44         return;
    45     }
    46     down(k,l,r);
    47     update(L,l,mid,x,y,z);
    48     update(R,mid+1,r,x,y,z);
    49     f[k]=merge(f[L],f[R]);
    50 }
    51 pii query(int k,int l,int r,int x,int y){
    52     if ((l>y)||(x>r))return mp(0,0);
    53     if ((x<=l)&&(r<=y))return f[k];
    54     down(k,l,r);
    55     return merge(query(L,l,mid,x,y),query(R,mid+1,r,x,y));
    56 }
    57 int main(){
    58     inv[0]=inv[1]=1;
    59     for(int i=2;i<N;i++)inv[i]=(ll)(mod-mod/i)*inv[mod%i]%mod;
    60     scanf("%d",&t);
    61     while (t--){
    62         scanf("%d%d",&n,&m);
    63         for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    64         for(int i=1;i<=m;i++){
    65             scanf("%d%d",&q[i].l,&q[i].r);
    66             q[i].id=i;
    67         }
    68         sort(q+1,q+m+1);
    69         mn[0]=mx[0]=0;
    70         memset(tag,0,sizeof(tag));
    71         memset(f,0,sizeof(f));
    72         for(int i=1,j=1;i<=n;i++){
    73             update(1,1,n,i,i,mp(2*a[i]%mod,(ll)2*(i-1)*a[i]%mod));
    74             while ((mx[0])&&(a[mx[mx[0]]]<a[i])){
    75                 int x=mx[mx[0]],y=mx[--mx[0]];
    76                 update(1,1,n,y+1,x,mp((a[i]-a[x]+mod)%mod,(ll)(i-1)*(a[i]-a[x]+mod)%mod));
    77             }
    78             while ((mn[0])&&(a[mn[mn[0]]]>a[i])){
    79                 int x=mn[mn[0]],y=mn[--mn[0]];
    80                 update(1,1,n,y+1,x,mp((a[i]-a[x]+mod)%mod,(ll)(i-1)*(a[i]-a[x]+mod)%mod));
    81             }
    82             mx[++mx[0]]=mn[++mn[0]]=i;
    83             while ((j<=m)&&(q[j].r==i)){
    84                 pii o=query(1,1,n,q[j].l,i);
    85                 ans[q[j].id]=((ll)i*o.fi-o.se+mod)%mod*inv[i-q[j].l+2]%mod*inv[i-q[j].l+1]%mod;
    86                 j++;
    87             }
    88         }
    89         for(int i=1;i<=m;i++)printf("%d
    ",ans[i]);
    90     }
    91     return 0;
    92 } 
    View Code
  • 相关阅读:
    mysql查询字段时实现左右补零
    两种方法获取MyBatis刚刚插入的id
    SpringBoot扫描包提示找不到mapper的问题
    如何删除mac keeper
    mongodb如何设置主键自增
    java数组和字符串相互转换
    algid parse error, not a sequence错误
    java数字转换成文字方法
    maven的groupid和artifactId
    mysql中的日期转换函数(类似oracle中的to_date)
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/15091203.html
Copyright © 2011-2022 走看看