给定一个长度为 n n n的序列,有 n n n个操作,区间加法和单点询问
将序列分成 s q r t ( n ) sqrt(n) sqrt(n)个块
对于一段区间修改,分两种情况讨论:
如果修改区间在一个块中,则暴力修改 a [ i ] a[i] a[i]的值
如果修改区间不在一个块中:
对于最左边和最右边的块,暴力修改
中间的整块维护一个块的 l a z y lazy lazy值
时间复杂度 O ( ( n / m ) + m ) O((n/m)+m) O((n/m)+m),根据均值不等式, m = s q r t ( n ) m=sqrt(n) m=sqrt(n)时最优
#include
using namespace std;
#define maxn 50010
int n,a[maxn],L[maxn],R[maxn],t,pos[maxn],la[maxn];
inline int read_() {
int x_=0,f_=1;char c_=getchar();
while(c_<'0'||c_>'9') {if(c_=='-') f_=-1;c_=getchar();}
while(c_>='0'&&c_<='9') {x_=(x_<<1)+(x_<<3)+c_-'0';c_=getchar();}
return x_*f_;
}
inline void update_(int l,int r,int w) {
int LL=pos[l],RR=pos[r];
if(LL==RR) for(int i=l;i<=r;++i) a[i]+=w;
else {
for(int i=l;i<=R[LL];++i) a[i]+=w;
for(int i=L[RR];i<=r;++i) a[i]+=w;
for(int i=LL+1;i<=RR-1;++i) la[i]+=w;
}
}
void readda_() {
n=read_();
for(int i=1;i<=n;++i) a[i]=read_();
t=sqrt(n);//块的大小亦块数,t*t=n
for(int i=1;i<=t;++i) {
L[i]=(i-1)*t+1;
R[i]=i*t;
}
if(R[t]<n) {++t;L[t]=R[t-1]+1;R[t]=n;}
for(int i=1;i<=t;++i) {
for(int j=L[i];j<=R[i];++j) {
pos[j]=i;//每个点属于哪个块
}
}
for(int i=1;i<=n;++i) {
int pd=read_(),l=read_(),r=read_(),c=read_();
if(!pd) update_(l,r,c);
else printf("%d\n",a[r]+la[pos[r]]);
}
}
int main() {
freopen("a.txt","r",stdin);
readda_();
return 0;
}
给出一个长为 n n n的数列,以及 n n n个操作,操作涉及区间加法,询问区间内小于某个值 x x x的元素个数。
要快速查询一个区间小于 x x x的数有多少,在区间有序的情况下我们可以使用二分 l o w e r lower lower_ b o u n d bound bound
维护出块之后,给每个块内排序,使块内元素有序
考虑修改:
如果一整个块都加上一个数,不影响块内元素的相对大小
如果修改一个块内的部分的数,则有可能会影响相对大小,在修改完之后,重新排序
考虑询问:
如果询问一整个块的话使用二分
否则暴力询问
#include
using namespace std;
#define maxn 50010
#define maxt 225
int n,a[maxn],L[maxt],R[maxt],pos[maxn],t,la[maxt];
vector <int >e[maxt];
inline int read_() {
int x_=0,f_=1;char c_=getchar();
while(c_<'0'||c_>'9') {if(c_=='-') f_=-1;c_=getchar();}
while(c_>='0'&&c_<='9') {x_=(x_<<1)+(x_<<3)+c_-'0';c_=getchar();}
return x_*f_;
}
inline void resert_(int x) {
e[x].clear();
for(int i=L[x];i<=R[x];++i) e[x].push_back(a[i]);
sort(e[x].begin(),e[x].end());
}
inline void update_(int l,int r,int w) {
int LL=pos[l],RR=pos[r];
if(LL==RR) {
for(int i=l;i<=r;++i) a[i]+=w;
resert_(LL);
}
else {
for(int i=l;i<=R[LL];++i) a[i]+=w;
resert_(LL);
for(int i=L[RR];i<=r;++i) a[i]+=w;
resert_(RR);
for(int i=LL+1;i<=RR-1;++i) la[i]+=w;
}
}
inline int query_(int l,int r,int w) {
int LL=pos[l],RR=pos[r];
int ans=0;
if(LL==RR) {
for(int i=l;i<=r;++i) {
if(a[i]+la[pos[i]]<w) ++ans;
}
}
else {
for(int i=l;i<=R[LL];++i) {
if(a[i]+la[pos[i]]<w) ++ans;
}
for(int i=L[RR];i<=r;++i) {
if(a[i]+la[pos[i]]<w) ++ans;
}
for(int i=LL+1;i<=RR-1;++i) {
ans+=lower_bound(e[i].begin(),e[i].end(),w-la[i])-e[i].begin();
}
}
return ans;
}
void readda_() {
n=read_();
for(int i=1;i<=n;++i) a[i]=read_();
t=sqrt(n);
for(int i=1;i<=t;++i) {
L[i]=(i-1)*t+1;
R[i]=i*t;
}
if(R[t]<n) {++t;L[t]=R[t-1]+1;R[t]=n;}
for(int i=1;i<=t;++i) {
for(int j=L[i];j<=R[i];++j) {
pos[j]=i;
e[i].push_back(a[j]);
}
sort(e[i].begin(),e[i].end());
}
for(int i=1;i<=n;++i) {
int pd=read_(),l=read_(),r=read_(),c=read_();
if(!pd) update_(l,r,c);
else printf("%d\n",query_(l,r,c*c));
}
}
int main() {
freopen("a.txt","r",stdin);
readda_();
return 0;
}
#include
using namespace std;
#define maxn 100010
#define maxt 330
int t,n,a[maxn],L[maxt],R[maxt],pos[maxn],la[maxt];
bool vis[maxt];
vector <int > e[maxt];
inline int read_() {
int x_=0,f_=1;char c_=getchar();
while(c_<'0'||c_>'9') {if(c_=='-') f_=-1;c_=getchar();}
while(c_>='0'&&c_<='9') {x_=(x_<<1)+(x_<<3)+c_-'0';c_=getchar();}
return x_*f_;
}
inline void resert_(int x) {
e[x].clear();
for(int i=L[x];i<=R[x];++i) e[x].push_back(a[i]);
sort(e[x].begin(),e[x].end());
vis[x]=0;
}
inline void update_(int l,int r,int w) {
int LL=pos[l],RR=pos[r];
if(LL==RR) {
for(int i=l;i<=r;++i) a[i]+=w;
vis[LL]=1;
}
else {
for(int i=l;i<=R[LL];++i) a[i]+=w;
vis[LL]=1;
for(int i=L[RR];i<=r;++i) a[i]+=w;
vis[RR]=1;
for(int i=LL+1;i<=RR-1;++i) la[i]+=w;
}
}
inline int query_(int l,int r,int w) {
int LL=pos[l],RR=pos[r];
if(LL==RR) {
int ans=-1;
for(int i=l;i<=r;++i) {
if(a[i]+la[pos[i]]<w) {
ans=max(ans,a[i]+la[pos[i]]);
}
}
return ans;
}
else {
int ans=-1;
for(int i=l;i<=R[LL];++i) {
if(a[i]+la[pos[i]]<w) {
ans=max(ans,a[i]+la[pos[i]]);
}
}
for(int i=L[RR];i<=r;++i) {
if(a[i]+la[pos[i]]<w) {
ans=max(ans,a[i]+la[pos[i]]);
}
}
for(int i=LL+1;i<=RR-1;++i) {
if(vis[i]) resert_(i);
int AKIOI=lower_bound(e[i].begin(),e[i].end(),w-la[i])-e[i].begin();
if(!AKIOI) continue;
ans=max(ans,e[i][AKIOI-1]+la[i]);
}
return ans;
}
}
void readda_() {
n=read_();
for(int i=1;i<=n;++i) a[i]=read_();
t=sqrt(n);
for(int i=1;i<=t;++i) {
L[i]=(i-1)*t+1;
R[i]=i*t;
}
if(R[t]<n) {++t;L[t]=R[t-1]+1;R[t]=n;}
for(int i=1;i<=t;++i) {
for(int j=L[i];j<=R[i];++j) {
pos[j]=i;
e[i].push_back(a[j]);
}
sort(e[i].begin(),e[i].end());
}
for(int i=1;i<=n;++i) {
int pd=read_(),l=read_(),r=read_(),c=read_();
if(!pd) update_(l,r,c);
else printf("%d\n",query_(l,r,c));
}
}
int main() {
freopen("a.txt","r",stdin);
readda_();
return 0;
}
#include
using namespace std;
#define maxn 100010
#define maxt 330
int n,L[maxt],R[maxt],la[maxt],a[maxn],t,pos[maxn];
set <int > e[maxt];
inline int read_() {
int x_=0,f_=1;char c_=getchar();
while(c_<'0'||c_>'9') {if(c_=='-') f_=-1;c_=getchar();}
while(c_>='0'&&c_<='9') {x_=(x_<<1)+(x_<<3)+c_-'0';c_=getchar();}
return x_*f_;
}
inline void update_(int l,int r,int w) {
int LL=pos[l],RR=pos[r];
if(LL==RR) {
for(int i=l;i<=r;++i) {
e[LL].erase(a[i]);
a[i]+=w;
e[LL].insert(a[i]);
}
}
else {
for(int i=l;i<=R[LL];++i) {
e[LL].erase(a[i]);
a[i]+=w;
e[LL].insert(a[i]);
}
for(int i=L[RR];i<=r;++i) {
e[RR].erase(a[i]);
a[i]+=w;
e[RR].insert(a[i]);
}
for(int i=LL+1;i<=RR-1;++i) la[i]+=w;
}
}
inline int query_(int l,int r,int w) {
int LL=pos[l],RR=pos[r];
if(LL==RR) {
int ans=-1,AKIOI;
for(int i=l;i<=r;++i) {
AKIOI=a[i]+la[LL];
if(AKIOI<w) ans=max(ans,AKIOI);
}
return ans;
}
else {
int ans=-1,AKIOI;
for(int i=l;i<=R[LL];++i) {
AKIOI=a[i]+la[LL];
if(AKIOI<w) ans=max(ans,AKIOI);
}
for(int i=L[RR];i<=r;++i) {
AKIOI=a[i]+la[RR];
if(AKIOI<w) ans=max(ans,AKIOI);
}
for(int i=LL+1;i<=RR-1;++i) {
set<int> :: iterator it=e[i].lower_bound(w-la[i]);
if(it==e[i].begin()) continue;
--it;
ans=max(ans,*it+la[i]);
}
return ans;
}
}
void readda_() {
n=read_();
for(int i=1;i<=n;++i) a[i]=read_();
t=sqrt(n);
for(int i=1;i<=t;++i) {
L[i]=(i-1)*t+1;
R[i]=i*t;
}
if(R[t]<n) {++t;L[t]=R[t-1]+1;R[t]=n;}
for(int i=1;i<=t;++i) {
for(int j=L[i];j<=R[i];++j) {
pos[j]=i;
e[i].insert(a[j]);
}
}
for(int i=1;i<=n;++i) {
int pd=read_(),l=read_(),r=read_(),c=read_();
if(!pd) update_(l,r,c);
else printf("%d\n",query_(l,r,c));
}
}
int main() {
freopen("a.txt","r",stdin);
readda_();
return 0;
}
#include
using namespace std;
#define maxn 50010
#define maxt 240
int n,L[maxt],R[maxt],pos[maxn],t;
long long a[maxn],sum[maxt],la[maxt];
inline long long read_() {
long long x_=0,f_=1;char c_=getchar();
while(c_<'0'||c_>'9') {if(c_=='-') f_=-1;c_=getchar();}
while(c_>='0'&&c_<='9') {x_=(x_<<1)+(x_<<3)+c_-'0';c_=getchar();}
return x_*f_;
}
inline void update_(int l,int r,int w) {
int LL=pos[l],RR=pos[r];
if(LL==RR) {
for(int i=l;i<=r;++i) {
a[i]+=w;
sum[LL]+=w;
}
}
else {
for(int i=l;i<=R[LL];++i) {
a[i]+=w;
sum[LL]+=w;
}
for(int i=L[RR];i<=r;++i) {
a[i]+=w;
sum[RR]+=w;
}
for(int i=LL+1;i<=RR-1;++i) la[i]+=w;
}
}
inline long long query_(int l,int r) {
int LL=pos[l],RR=pos[r];
long long ans=0;
if(LL==RR) {
for(int i=l;i<=r;++i) ans+=a[i];
ans+=(r-l+1)*la[LL];
}
else {
for(int i=l;i<=R[LL];++i) ans+=a[i];
ans+=(R[LL]-l+1)*la[LL];
for(int i=L[RR];i<=r;++i) ans+=a[i];
ans+=(r-L[RR]+1)*la[RR];
for(int i=LL+1;i<=RR-1;++i) {
ans+=sum[i];
ans+=(R[i]-L[i]+1)*la[i];
}
}
return ans;
}
void readda_() {
n=read_();
for(int i=1;i<=n;++i) a[i]=read_();
t=sqrt(n);
for(int i=1;i<=t;++i) {
L[i]=(i-1)*t+1;
R[i]=i*t;
}
if(R[t]<n) {++t;L[t]=R[t-1]+1;R[t]=n;}
for(int i=1;i<=t;++i) {
for(int j=L[i];j<=R[i];++j) {
pos[j]=i;
sum[i]+=a[j];
}
}
for(int i=1;i<=n;++i) {
int pd=read_(),l=read_(),r=read_(),c=read_();
if(!pd) update_(l,r,c);
else printf("%lld\n",query_(l,r)%(c+1));
}
}
int main() {
freopen("a.txt","r",stdin);
readda_();
return 0;
}
#include
using namespace std;
#define maxn 50010
#define maxt 240
int n,a[maxn],L[maxt],R[maxt],sum[maxt],pos[maxn],t;
bool flag[maxt];
inline int read_() {
int x_=0,f_=1;char c_=getchar();
while(c_<'0'||c_>'9') {if(c_=='-') f_=-1;c_=getchar();}
while(c_>='0'&&c_<='9') {x_=(x_<<1)+(x_<<3)+c_-'0';c_=getchar();}
return x_*f_;
}
inline void solve_(int x) {
if(flag[x]) return ;
flag[x]=1;
for(int i=L[x];i<=R[x];++i) {
sum[x]-=a[i];
a[i]=sqrt(a[i]);
sum[x]+=a[i];
if(a[i]>1) flag[x]=0;
}
}
inline void update_(int l,int r,int w) {
int LL=pos[l],RR=pos[r];
if(LL==RR) {
for(int i=l;i<=r;++i) {
sum[LL]-=a[i];
a[i]=sqrt(a[i]);
sum[LL]+=a[i];
}
}
else {
for(int i=l;i<=R[LL];++i){
sum[LL]-=a[i];
a[i]=sqrt(a[i]);
sum[LL]+=a[i];
}
for(int i=L[RR];i<=r;++i) {
sum[RR]-=a[i];
a[i]=sqrt(a[i]);
sum[RR]+=a[i];
}
for(int i=LL+1;i<=RR-1;++i) solve_(i);
}
}
inline int query_(int l,int r) {
int LL=pos[l],RR=pos[r];
int ans=0;
if(LL==RR) {
for(int i=l;i<=r;++i) ans+=a[i];
}
else {
for(int i=l;i<=R[LL];++i) ans+=a[i];
for(int i=L[RR];i<=r;++i) ans+=a[i];
for(int i=LL+1;i<=RR-1;++i) ans+=sum[i];
}
return ans;
}
void readda_() {
n=read_();
for(int i=1;i<=n;++i) a[i]=read_();
t=sqrt(n);
for(int i=1;i<=t;++i) {
L[i]=(i-1)*t+1;
R[i]=i*t;
}
if(R[t]<n) {++t;L[t]=R[t-1]+1;R[t]=n;}
for(int i=1;i<=t;++i) {
for(int j=L[i];j<=R[i];++j) {
pos[j]=i;
sum[i]+=a[j];
}
}
for(int i=1;i<=n;++i) {
int pd=read_(),l=read_(),r=read_(),c=read_();
if(!pd) update_(l,r,c);
else printf("%d\n",query_(l,r));
}
}
int main() {
freopen("a.txt","r",stdin);
readda_();
return 0;
}