zoukankan      html  css  js  c++  java
  • BZOJ3745 : [Coci2014]Norma

    考虑枚举右端点,用线段树维护[i,nowr]的答案。

    当右端点向右延伸时,需要知道它前面第一个比它大/小的数的位置,这里面的最值将发生改变,这个使用单调队列求出,然后将所有的l都加1。

    注意常数优化。

    #include<cstdio>
    #define PB int mid=(a+b)>>1,l=x<<1,r=l|1;if(T[x].tx)cmax1(l,T[x].tx),cmax1(r,T[x].tx),T[x].tx=0;if(T[x].tn)cmin1(l,T[x].tn),cmin1(r,T[x].tn),T[x].tn=0;if(T[x].tl)clen1(l,T[x].tl),clen1(r,T[x].tl),T[x].tl=0;
    #define UP T[x].sx=(T[l].sx+T[r].sx)%P;T[x].sn=(T[l].sn+T[r].sn)%P;T[x].sl=(T[l].sl+T[r].sl)%P;T[x].sxn=(T[l].sxn+T[r].sxn)%P;T[x].sxl=(T[l].sxl+T[r].sxl)%P;T[x].snl=(T[l].snl+T[r].snl)%P;T[x].sxnl=(T[l].sxnl+T[r].sxnl)%P;
    typedef long long ll;
    const int N=500010,P=1000000000;
    int n,i,v[N],q1[N],q2[N],t1,t2,ans;
    struct node{int sx,sn,sl,sxn,sxl,snl,sxnl,tx,tn,tl,l;}T[1050000];
    inline void read(int&a){char c;while(!(((c=getchar())>='0')&&(c<='9')));a=c-'0';while(((c=getchar())>='0')&&(c<='9'))(a*=10)+=c-'0';}
    void build(int x,int a,int b){
      T[x].l=b-a+1;
      if(a==b)return;
      int mid=(a+b)>>1;
      build(x<<1,a,mid),build(x<<1|1,mid+1,b);
    }
    inline void cmax1(int x,ll p){
      T[x].sx=p*T[x].l%P;
      T[x].sxn=p*T[x].sn%P;
      T[x].sxl=p*T[x].sl%P;
      T[x].sxnl=p*T[x].snl%P;
      T[x].tx=p;
    }
    inline void cmin1(int x,ll p){
      T[x].sn=p*T[x].l%P;
      T[x].sxn=p*T[x].sx%P;
      T[x].snl=p*T[x].sl%P;
      T[x].sxnl=p*T[x].sxl%P;
      T[x].tn=p;
    }
    inline void clen1(int x,ll p){
      T[x].sl=(p*T[x].l+T[x].sl)%P;
      T[x].sxl=(p*T[x].sx+T[x].sxl)%P;
      T[x].snl=(p*T[x].sn+T[x].snl)%P;
      T[x].sxnl=(p*T[x].sxn+T[x].sxnl)%P;
      T[x].tl=(T[x].tl+p)%P;
    }
    void cmax(int x,int a,int b,int c){
      if(c<=a&&b<=i){cmax1(x,v[i]);return;}
      PB
      if(c<=mid)cmax(l,a,mid,c);
      if(i>mid)cmax(r,mid+1,b,c);
      UP
    }
    void cmin(int x,int a,int b,int c){
      if(c<=a&&b<=i){cmin1(x,v[i]);return;}
      PB
      if(c<=mid)cmin(l,a,mid,c);
      if(i>mid)cmin(r,mid+1,b,c);
      UP
    }
    void clen(int x,int a,int b){
      if(b<=i){clen1(x,1);return;}
      PB
      clen(l,a,mid);
      if(i>mid)clen(r,mid+1,b);
      UP
    }
    int main(){
      read(n);
      for(i=1;i<=n;i++)read(v[i]);
      build(1,1,n);
      for(i=1;i<=n;q1[++t1]=q2[++t2]=i++){
        while(t1&&v[q1[t1]]<v[i])t1--;
        while(t2&&v[q2[t2]]>v[i])t2--;
        cmax(1,1,n,q1[t1]+1),cmin(1,1,n,q2[t2]+1),clen(1,1,n);
        ans=(ans+T[1].sxnl)%P;
      }
      return printf("%d",ans),0;
    }
    

      

  • 相关阅读:
    Swift3 重写一个带占位符的textView
    Swift3 使用系统UIAlertView方法做吐司效果
    Swift3 页面顶部实现拉伸效果代码
    Swift3 倒计时按钮扩展
    iOS 获取当前对象所在的VC
    SpringBoot在IDEA下使用JPA
    hibernate 异常a different object with the same identifier value was already associated with the session
    SpringCloud IDEA 教学 番外篇 后台运行Eureka服务注册中心
    SpringCloud IDEA 教学 (五) 断路器控制台(HystrixDashboard)
    SpringCloud IDEA 教学 (四) 断路器(Hystrix)
  • 原文地址:https://www.cnblogs.com/clrs97/p/4403205.html
Copyright © 2011-2022 走看看