• LOJ 6029. 「雅礼集训 2017 Day1」市场


    思路:线段树+转化

    提交:2次

    错因:由于智障没有判断左右端点ORZ

    题解:

    主要是如何把区间除下取整转化成更适合线段树的一些操作。
    给定除数 (d) ,对于一段区间,若区间只包含 (k*d)(k*d-1) ,我们可以转化成区间减,因为此时做完除法,新的数与原数的差相等,即

    [k*d-(k*d)/d=k*d-1-(k*d-1)/d ]

    [k*d-k=k*d-1-(k-1) ]

    所以我们就把区间除变成了区间减辣!(但是复杂度玄学)

    代码:

    #include<cstdio>
    #include<iostream>
    #include<cmath>
    #define R register int
    #define ll long long
    using namespace std;
    namespace Luitaryi {
    static char B[1<<15],*S=B,*T=B;
    #define getchar() (S==T&&(T=(S=B)+fread(B,1,1<<15,stdin),S==T)?EOF:*S++)
    template<class I> inline I g(I& x) { x=0; register I f=1;
      register char ch; while(!isdigit(ch=getchar())) f=ch=='-'?-1:f;
      do x=x*10+(ch^48); while(isdigit(ch=getchar())); return x*=f;
    } const int N=1e5+10; const ll Inf=1e+15;
    int n,m,LL,RR,d;
    ll mx[N<<2],mn[N<<2],sum[N<<2],tg[N<<2];
    #define ls (tr<<1)
    #define rs (tr<<1|1)
    inline void upd(R tr) {
      sum[tr]=sum[ls]+sum[rs];
      mx[tr]=max(mx[ls],mx[rs]);
      mn[tr]=min(mn[ls],mn[rs]);
    }
    inline void build(R tr,R l,R r) {
      if(l==r) {sum[tr]=mn[tr]=g(mx[tr]); return ;} R md=l+r>>1;
      build(ls,l,md),build(rs,md+1,r); upd(tr);
    }
    inline void spread(R tr,R l,R r,R md) { if(tg[tr]==0) return; 
      sum[ls]+=tg[tr]*(md-l+1),sum[rs]+=tg[tr]*(r-md); 
      mn[ls]+=tg[tr],mx[ls]+=tg[tr],mn[rs]+=tg[tr],mx[rs]+=tg[tr];
      tg[ls]+=tg[tr],tg[rs]+=tg[tr]; tg[tr]=0;
    }
    inline void add(R tr,R l,R r) {
      if(LL<=l&&r<=RR) {sum[tr]+=(r-l+1)*d,mx[tr]+=d,mn[tr]+=d,tg[tr]+=d; return ;}
      R md=l+r>>1; spread(tr,l,r,md); if(LL<=md) add(ls,l,md); 
      if(RR>md) add(rs,md+1,r); upd(tr);
    }
    inline void div(R tr,R l,R r) {
      if(LL<=l&&r<=RR) if((mx[tr]==mn[tr]||(mx[tr]==mn[tr]+1&&mx[tr]%d==0))) { 
        R c=mx[tr]-floor(1.0*mx[tr]/d);
        sum[tr]-=(r-l+1)*c; mx[tr]-=c,mn[tr]-=c,tg[tr]-=c; return ;
      } R md=l+r>>1; spread(tr,l,r,md);
      if(LL<=md) div(ls,l,md); if(RR>md) div(rs,md+1,r); upd(tr);
    }
    inline ll querymn(R tr,R l,R r) {
      if(LL<=l&&r<=RR) return mn[tr];  R md=l+r>>1; spread(tr,l,r,md);
      register ll ret=Inf; if(LL<=md) ret=min(ret,querymn(ls,l,md)); 
      if(RR>md) ret=min(ret,querymn(rs,md+1,r)); return ret;
    }
    inline ll query(R tr,R l,R r) {
      if(LL<=l&&r<=RR) return sum[tr]; R md=l+r>>1; spread(tr,l,r,md);
      register ll ret=0; if(LL<=md) ret+=query(ls,l,md); 
      if(RR>md) ret+=query(rs,md+1,r); return ret;
    }
    inline void main() {
      g(n),g(m); build(1,1,n);
      R op; while(m--) {
        g(op),g(LL),g(RR),++LL,++RR; 
        if(op==1) g(d),add(1,1,n);
        if(op==2) g(d),div(1,1,n);
        if(op==3) printf("%lld
    ",querymn(1,1,n));
        if(op==4) printf("%lld
    ",query(1,1,n));
      } 
    }
    } signed main() {Luitaryi::main(); return 0;}
    

    2019.08.30
    70

  • 相关阅读:
    大家一起写mvc(二)
    大家一起写mvc(一)
    jquery读取XML 生成页面文件
    jquery点击区域显示或隐藏DIV,点击非该DIV的地方隐藏该DIV
    struts2 iterator排序
    解决JS传参中文乱码
    关于解决 请求被中止:无法建立SSL / TLS安全通道
    查看sqlserver被锁的表以及如何解锁
    查询sqlserver数据库视图、存储过程等包含特定的字符串
    C#中查询字符串中是否包含指定字符/串,使用IndexOf还是Contains?
  • 原文地址:https://www.cnblogs.com/Jackpei/p/11437556.html
Copyright © 2020-2023  润新知