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;
}
posted @ 2023-06-24 13:55  alex_liu09  阅读(15)  评论(0)    收藏  举报