雅礼集训 day1 市场

SOL:

 我们发现每次除操作都会使这个序列趋于相同。我们定义 势能函数 W=序列中的不同数除x次2会趋于相同。

 我们发现每次dla操作最多令W 增加log,而一次除操作至少会让W -1,

 我们发现Wmax是O(nlogn+qlog )的,而每次让W-1的代价是1

  故复杂度是小于O(nlogn )的。

 

#include<bits/stdc++.h>
#define Mid (l+r>>1)
#define ls o<<1,l,Mid
#define rs o<<1|1,Mid+1,r
#define inf (1<<29)
#define N 400007
#define LL long long
long long sum[N],ans;
int mx[N],mn[N],lazy[N],mii,n,q,op,l,r,dla;
#define sight(x) ('0'<=x&&x<='9')
template <class T>
inline void read(T &x){
    static char c;static int b;
    for (b=1,c=getchar();!sight(c);c=getchar())if (c=='-') b=-1;
    for (x=0;sight(c);c=getchar())x=x*10+c-48; x*=b;
}
void write(LL x){if (x<10) {putchar('0'+x); return;} write(x/10); putchar('0'+x%10);}
inline void writeln(LL x){ if (x<0) putchar('-'),x*=-1; write(x); putchar('\n'); }
inline void writel(LL x){ if (x<0) putchar('-'),x*=-1; write(x); putchar(' '); }
using namespace std;
inline int chu(int x,int y){
    return x/y+(x%y<0?-1:0);
}
inline void up(int x){
    sum[x]=sum[x<<1]+sum[x<<1|1];
    mx[x]=max(mx[x<<1],mx[x<<1|1]);
    mn[x]=min(mn[x<<1],mn[x<<1|1]);
}
inline void down(int x,int l,int r){
    sum[x<<1]+=lazy[x]*(Mid-l+1); mx[x<<1]+=lazy[x]; mn[x<<1]+=lazy[x]; lazy[x<<1]+=lazy[x];
    sum[x<<1|1]+=lazy[x]*(r-Mid); mx[x<<1|1]+=lazy[x]; mn[x<<1|1]+=lazy[x]; lazy[x<<1|1]+=lazy[x];
    lazy[x]=0;
}
void build(int o,int l,int r){
    if (l==r) {
        read(sum[o]); 
        mx[o]=mn[o]=sum[o];
        return;
    }
    build(ls); build(rs);
    up(o);
}
void add(int o,int l,int r,int L,int R,int dla){
    if (L<=l&&r<=R) {
        sum[o]+=(r-l+1)*dla; mx[o]+=dla; mn[o]+=dla;
        lazy[o]+=dla; return;
    }
    if (lazy[o]&&l!=r) down(o,l,r);
    if (L<=Mid) add(ls,L,R,dla);
    if (R> Mid) add(rs,L,R,dla);
    up(o);
}
void query(int o,int l,int r,int L,int R){
    if (L<=l&&r<=R) {
        mii=min(mii,mn[o]); ans+=sum[o]; return;
    }
    if (lazy[o]&&l!=r) down(o,l,r);
    if (L<=Mid) query(ls,L,R);
    if (R> Mid) query(rs,L,R);
}
void upt(int o,int l,int r,int L,int R,int dla){
    if (L<=l&&r<=R&&chu(mx[o],dla)-mx[o]==chu(mn[o],dla)-mn[o]) {
        add(o,l,r,L,R,chu(mx[o],dla)-mx[o]); return;
    }
    if (lazy[o]&&l!=r) down(o,l,r);
    if (L<=Mid) upt(ls,L,R,dla);
    if (R> Mid) upt(rs,L,R,dla);
    up(o);
}
void dfs(int o,int l,int r){
    if (l==r) {
        writel(sum[o]); return;
    }
    if (lazy[o]&&l!=r) down(o,l,r);
    dfs(ls); dfs(rs);
}
signed main () {
//    cerr<<chu(-2,3)<<endl;
//    freopen("a.in","r",stdin);
    read(n); read(q);
    build(1,1,n);
    while (q--) {
        read(op);
        if (op==1) {
            read(l); read(r); read(dla);
            add(1,1,n,l+1,r+1,dla);
        }else  if (op==2) {
            read(l); read(r); read(dla);
            upt(1,1,n,l+1,r+1,dla);
//            dfs(1,1,n); writeln(233);
        }else  if (op==3) {
            ans=0; mii=inf;
            read(l); read(r);
            query(1,1,n,l+1,r+1);
            writeln(mii);
        }else{
            ans=0; mii=inf;
            read(l); read(r);
            query(1,1,n,l+1,r+1);
            writeln(ans);
        }
    } return 0;
}

 

  

posted @ 2018-04-10 20:55  泪寒之雪  阅读(398)  评论(0编辑  收藏  举报