今天考試考了一些神仙數據結構
T1 線段樹維護區間加,區間開方,區間和
(數據範圍:5e5)
T2 線段樹維護區間加,區間除,區間和,區間最值
對於這些題目,就像是之前考的區間與,區間或一樣,除法,開方的操作會讓各個數字之間越來越相近,最後變成一串一串連續的數字都是一樣的,所以對於這一部分的操作我們一定程度上使用暴力,而如果一段都相等就相當於直接進行區間剪髮的操作
那麼我們來看如何判斷區間一段都相等,那我們只需要維護區間的最值,最小值==最大值就完全相等了
然後.....代碼.....被 \(yurzhang\) 神犇卡常,然後 \(huyufeifei\) 巨佬把我的 \(T1\) 改的面目全非......
爲了大常數的尊嚴 ,還是放被卡常的代碼
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define re register
#define gc getchar()
inline ll read()
{
re char c(gc);re ll x(0);
while(c<'0'||c>'9') c=gc;
while(c>='0'&&c<='9') x=x*10+c-48,c=gc;
return x;
}
const int N=5e5+10;
ll a[N],s[N<<2],minn[N<<2],maxx[N<<2],add[N<<2];
#define mid ((l+r)>>1)
#define ls id<<1
#define rs id<<1|1
inline void pushup(int id)
{
s[id]=s[ls]+s[rs];
minn[id]=min(minn[ls],minn[rs]);
maxx[id]=max(maxx[ls],maxx[rs]);
}
inline void pushdown(int id,int l,int r)
{
if(add[id]!=0)
{
re int lx=mid-l+1,rx=r-mid;
add[ls]+=add[id];
add[rs]+=add[id];
s[ls]+=add[id]*lx;
s[rs]+=add[id]*rx;
minn[rs]+=add[id];
minn[ls]+=add[id];
maxx[ls]+=add[id];
maxx[rs]+=add[id];
add[id]=0;
}
}
void built(int id,int l,int r)
{
if(l==r)
{
s[id]=a[l];
minn[id]=a[l];
maxx[id]=a[l];
return ;
}
built (ls,l,mid);
built (rs,mid+1,r);
pushup(id);
}
void change(int id,int l,int r,int L,int R,ll x)
{
if(l>=L&&r<=R)
{
s[id]+=x*(r-l+1);
add[id]+=x;
minn[id]+=x;
maxx[id]+=x;
return;
}
pushdown(id,l,r);
if(mid>=L) change(ls,l,mid,L,R,x);
if(mid<R) change(rs,mid+1,r,L,R,x);
pushup(id);
}
void Change(int id,int l,int r,int L,int R)
{
if(l>=L&&r<=R&&floor(sqrt(maxx[id]))-maxx[id]==floor(sqrt(minn[id]))-minn[id])
{
ll d=floor(sqrt(maxx[id]))-maxx[id];
// cout<<maxx[id]<<' '<<d<<endl;
add[id]+=d;
maxx[id]+=d;
minn[id]+=d;
s[id]+=d*(r-l+1);
return;
}
pushdown(id,l,r);
if(L<=mid) Change(ls,l,mid,L,R);
if(mid<R) Change(rs,mid+1,r,L,R);
pushup(id);
}
ll query(int id,int l,int r,int L,int R)
{
if(l>=L&&r<=R) return s[id];
pushdown(id,l,r);
ll ans=0;
if(L<=mid) ans+=query(ls,l,mid,L,R);
if(R>mid) ans+=query(rs,mid+1,r,L,R);
return ans;
}
int n,m;
int main()
{
freopen("comp.in","r",stdin);
freopen("comp.out","w",stdout);
n=read(),m=read();
for(int i=1;i<=n;++i) a[i]=read();
built(1,1,n);
while(m--)
{
int op=read(),l=read(),r=read();
if(op==1) {ll x=read();change(1,1,n,l,r,x);}
if(op==2) {cout<<query(1,1,n,l,r)<<endl;}
if(op==3) {Change(1,1,n,l,r);}
}
return 0;
}
#include <bits/stdc++.h>
using namespace std;
#define re register
#define gc getchar()
inline int read()
{
re char c(gc);re int x(0);
while(c<'0'||c>'9') c=gc;
while(c>='0'&&c<='9') x=x*10+c-48,c=gc;
return x;
}
#define ll long long
const int N=1e5+10;
ll a[N],s[N<<2],minn[N<<2],maxx[N<<2],add[N<<2];
#define mid ((l+r)>>1)
#define ls id<<1
#define rs id<<1|1
inline void pushup(int id)
{
s[id]=s[ls]+s[rs];
minn[id]=min(minn[ls],minn[rs]);
maxx[id]=max(maxx[ls],maxx[rs]);
}
inline void pushdown(int id,int l,int r)
{
if(add[id]!=0)
{
re int lx=mid-l+1,rx=r-mid;
add[ls]+=add[id];
add[rs]+=add[id];
s[ls]+=add[id]*lx;
s[rs]+=add[id]*rx;
minn[rs]+=add[id];
minn[ls]+=add[id];
maxx[ls]+=add[id];
maxx[rs]+=add[id];
add[id]=0;
}
}
void built(int id,int l,int r)
{
if(l==r)
{
s[id]=a[l];
minn[id]=a[l];
maxx[id]=a[l];
return ;
}
built (ls,l,mid);
built (rs,mid+1,r);
pushup(id);
}
void change(int id,int l,int r,int L,int R,ll x)
{
if(l>=L&&r<=R)
{
s[id]+=x*(r-l+1);
add[id]+=x;
minn[id]+=x;
maxx[id]+=x;
return;
}
pushdown(id,l,r);
if(mid>=L) change(ls,l,mid,L,R,x);
if(mid<R) change(rs,mid+1,r,L,R,x);
pushup(id);
}
void Change(int id,int l,int r,int L,int R,ll x)
{
if (l >=L&&r<=R&&maxx[id]-floor(maxx[id]/x)==minn[id]-floor(minn[id]/x))
{
ll d=floor(maxx[id]/x)-maxx[id];
add[id]+=d;
maxx[id]+=d;
minn[id]+=d;
s[id]+=d*(r-l+1);
return;
}
pushdown(id,l,r);
if(L<=mid) Change(ls,l,mid,L,R,x);
if(mid<R) Change(rs,mid+1,r,L,R,x);
pushup(id);
}
ll query(int id,int l,int r,int L,int R)
{
if(l>=L&&r<=R) return s[id];
pushdown(id,l,r);
ll ans=0;
if(L<=mid) ans+=query(ls,l,mid,L,R);
if(R>mid) ans+=query(rs,mid+1,r,L,R);
return ans;
}
ll Query(int id,int l,int r,int L,int R)
{
if(l>=L&&r<=R) return maxx[id];
pushdown(id,l,r);
ll ans=0;
if(L<=mid) ans=max(ans,Query(ls,l,mid,L,R));
if(R>mid) ans=max(ans,Query(rs,mid+1,r,L,R));
return ans;
}
int n,m;
int main()
{
freopen("count.in","r",stdin);
freopen("count.out","w",stdout);
n=read(),m=read();
for(int i=1;i<=n;++i) a[i]=read();
built(1,1,n);
while(m--)
{
int op=read();
ll l=read(),r=read();
if(op==1) {int x=read();change(1,1,n,l,r,x);}
if(op==2) {cout<<query(1,1,n,l,r)<<endl;}
if(op==3) {cout<<Query(1,1,n,l,r)<<endl;}
if(op==4) {int x=read();Change(1,1,n,l,r,x);}
}
return 0;
}