CF438D The Child and Sequence 线段树水题
取模操作只需要暴力做就可以。我们只需要维护其最大值然后判断模数是否大于最大值,如果大于,那么就不用取模了,否则直接往下做。注意到每一个数最多被取模 \(\log\) 次,复杂度最多不超过 \(n\log^210^9\)
要注意不加 pushup
尽量不要加,因为如果,pushup
叶子节点就完蛋了。
\(4\) 秒还是可以过的。
#include<bits/stdc++.h>
#define dd double
#define ld long double
#define ll long long
#define int long long
#define uint unsigned int
#define ull unsigned long long
#define N 100010
#define M number
using namespace std;
const int INF=0x3f3f3f3f;
template<typename T> inline void read(T &x) {
x=0; int f=1;
char c=getchar();
for(;!isdigit(c);c=getchar()) if(c == '-') f=-f;
for(;isdigit(c);c=getchar()) x=x*10+c-'0';
x*=f;
}
template<typename T> inline T Max(T a,T b){
return a<b?b:a;
}
int n,m,a[N];
struct node{
int sum,maxx;
};
struct ST{
node p[N<<4];
inline void pushup(int k){
p[k].sum=p[k*2].sum+p[k*2+1].sum;
p[k].maxx=Max(p[k*2].maxx,p[k*2+1].maxx);
}
inline void build(int k,int l,int r){
if(l==r){p[k].sum=a[l];p[k].maxx=a[l];return;}
int mid=(l+r)>>1;
build(k*2,l,mid);build(k*2+1,mid+1,r);
pushup(k);
}
inline void change(int k,int l,int r,int x,int val){
if(l==r){p[k].sum=val;p[k].maxx=val;return;}
int mid=(l+r)>>1;
if(x<=mid) change(k*2,l,mid,x,val);
else change(k*2+1,mid+1,r,x,val);
pushup(k);
}
inline int ask_sum(int k,int l,int r,int z,int y){
if(l==z&&r==y){return p[k].sum;}
int mid=(l+r)>>1;
if(y<=mid) return ask_sum(k*2,l,mid,z,y);
else if(z>mid) return ask_sum(k*2+1,mid+1,r,z,y);
else return ask_sum(k*2,l,mid,z,mid)+ask_sum(k*2+1,mid+1,r,mid+1,y);
}//
inline void qumo(int k,int l,int r,int z,int y,int mod){
if(p[k].maxx<mod){return;}
if(l==r){p[k].sum%=mod;p[k].maxx=p[k].sum;return;}
int mid=(l+r)>>1;
if(y<=mid) qumo(k*2,l,mid,z,y,mod);
else if(z>mid) qumo(k*2+1,mid+1,r,z,y,mod);
else qumo(k*2,l,mid,z,mid,mod),qumo(k*2+1,mid+1,r,mid+1,y,mod);
pushup(k);
}
};
ST st;
signed main(){
// freopen("my.in","r",stdin);
// freopen("my.out","w",stdout);
read(n);read(m);
for(int i=1;i<=n;i++) read(a[i]);
st.build(1,1,n);
for(int i=1;i<=m;i++){
int op;int a,b;
read(op);read(a);read(b);
if(op==1) printf("%lld\n",st.ask_sum(1,1,n,a,b));
else if(op==2){int x;read(x);st.qumo(1,1,n,a,b,x);}
else if(op==3) st.change(1,1,n,a,b);
}
return 0;
}