CF438D The Child and Sequence
题面翻译
给定数列,区间查询和,区间取模,单点修改。
\(n, m \leq 10^5\)。
样例 #1
样例输入 #1
5 5
1 2 3 4 5
2 3 5 4
3 3 5
1 2 5
2 1 3 3
1 1 3
样例输出 #1
8
5
样例 #2
样例输入 #2
10 10
6 9 6 7 6 1 10 10 9 5
1 3 9
2 7 10 9
2 5 10 8
1 4 7
3 3 7
2 7 9 9
1 2 4
1 6 6
1 5 9
3 1 10
样例输出 #2
49
15
23
1
9
分析
由于区间取模最多只能进行 \(O(\log n)\) 次,所以直接搞就行了
#include<bits/stdc++.h>
#define int long long
using namespace std;
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&15),c=getchar();
return x*f;
}
int n,m,a[100005],sum[100005<<2],maxx[100005<<2];
void pushup(int num){sum[num]=sum[num<<1]+sum[num<<1|1],maxx[num]=max(maxx[num<<1],maxx[num<<1|1]);}
void build(int l,int r,int num){
if(l==r){
sum[num]=maxx[num]=a[l];
return;
}
int mid=l+r>>1;
build(l,mid,num<<1),build(mid+1,r,num<<1|1);
pushup(num);
}
void update(int l,int r,int num,int x,int y){
if(l==r){sum[num]=maxx[num]=y;return;}
int mid=l+r>>1;
if(x<=mid)update(l,mid,num<<1,x,y);
else update(mid+1,r,num<<1|1,x,y);
pushup(num);
}
void change(int l,int r,int num,int x,int y,int k){
if(x>r||y<l)return;
if(maxx[num]<k)return;
if(l==r){sum[num]%=k,maxx[num]%=k;return;}
int mid=l+r>>1;
change(l,mid,num<<1,x,y,k),change(mid+1,r,num<<1|1,x,y,k);
pushup(num);
}
int query(int l,int r,int num,int x,int y){
if(x>r||y<l)return 0;
if(x<=l&&r<=y)return sum[num];
int mid=l+r>>1;
return query(l,mid,num<<1,x,y)+query(mid+1,r,num<<1|1,x,y);
}
signed main(){
n=read(),m=read();
for(int i=1;i<=n;i++)a[i]=read();
build(1,n,1);
for(int i=1,opt,x,y,k;i<=m;i++){
opt=read();
if(opt==1)x=read(),y=read(),printf("%lld\n",query(1,n,1,x,y));
else if(opt==2)x=read(),y=read(),k=read(),change(1,n,1,x,y,k);
else x=read(),y=read(),update(1,n,1,x,y);
}
return 0;
}

浙公网安备 33010602011771号