雅礼集训 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; }