The Child and Sequence CodeForces - 438D(线段树)

版权声明:欢迎大家指正错误,有不同观点的欢迎评论,共同进步 https://blog.csdn.net/Sirius_han/article/details/81591298

The Child and Sequence

 题目链接:CodeForces - 438D

题意:一共n个数,三种操作:1  l  r :求区间[l, r]的和; 2  l   r   x :将区间[l, r]的所有数对x取模;  3   k   x:将k处的数改为x;

思路:如果区间的最大值都比要取模的数小,就不需要继续向下更新了,如果大,就看做单点更新;至于为什么不会T,恕在下太菜,不会证明,有兴趣可以看看这篇博客戳这里,虽然我并没有看懂,但觉有好像有那么点意思;

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+10;
struct node{
	int l, r;
	ll sum, maxx;
}tr[maxn<<2];
void pushup(int m){
	tr[m].sum=tr[m<<1].sum+tr[m<<1|1].sum;
	tr[m].maxx=max(tr[m<<1].maxx, tr[m<<1|1].maxx);
}
void build(int m, int l, int r){
	tr[m].l=l;
	tr[m].r=r;
	if(l==r){
		scanf("%lld", &tr[m].sum);
		tr[m].maxx=tr[m].sum;
		return;
	}
	int mid=(l+r)>>1;
	build(m<<1, l, mid);
	build(m<<1|1, mid+1, r);
	pushup(m);
}
void updata1(int m, int l, int r, ll mod){
	if(tr[m].maxx<mod) return;
	if(tr[m].l==tr[m].r){
		tr[m].sum%=mod;
		tr[m].maxx=tr[m].sum;\
		return;
	}
	int mid=(tr[m].l+tr[m].r)>>1;
	if(r<=mid) updata1(m<<1, l, r, mod);
	else if(l>mid) updata1(m<<1|1, l, r, mod);
	else{
		updata1(m<<1, l, mid, mod);
		updata1(m<<1|1, mid+1, r, mod);
	}
	pushup(m);
}
void updata2(int m, int inx, int k){
	if(tr[m].l==tr[m].r){
		tr[m].sum=k;
		tr[m].maxx=k;
		return;
	}
	int mid=(tr[m].l+tr[m].r)>>1;
	if(inx<=mid) updata2(m<<1, inx, k);
	else updata2(m<<1|1, inx, k);
	pushup(m);
}
ll query(int m, int l, int r){
	if(tr[m].l==l&&tr[m].r==r){
		return tr[m].sum;
	}
	int mid=(tr[m].l+tr[m].r)>>1;
	ll temp;
	if(r<=mid) temp=query(m<<1, l, r);
	else if(l>mid) temp=query(m<<1|1, l, r);
	else{
		temp=query(m<<1, l, mid)+query(m<<1|1, mid+1, r);
	}
	pushup(m);
	return temp;
}
int main(){
	int n, m;
	scanf("%d%d", &n, &m);
	build(1, 1, n);
	while(m--){
		int type;
		scanf("%d", &type);
		if(type==1){
			int l, r;
			scanf("%d%d", &l, &r);
			printf("%lld\n", query(1, l, r));
		}
		else if(type==2){
			int l, r;
			ll x;
			scanf("%d%d%lld", &l, &r, &x);
			updata1(1, l, r, x);
		}
		else{
			int inx;
			ll k;
			scanf("%d%lld", &inx, &k);
			updata2(1, inx, k);
		}
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/Sirius_han/article/details/81591298