Codeforces Round #250 (Div. 1) D. The Child and Sequence(线段树+区间求模+区间查询)

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/bnubeginner/article/details/86592815

先呈上原题链接[Codeforces Round #250 (Div. 1) D. The Child and Sequence]
题意:
给定一组数有三个操作:
区间每个值对 P P 求模;
单点修改
询问区间和

思路:
两棵线段树,一个维护区间最大值,一个维护区间和。
因为求模运算每次至少是折半的,所以对需要求模的暴力修改就行了。

坑点:

good luck and have fun!!!
附上代码:

#include<bits/stdc++.h>
#define pb push_back
#define mem(a,b) memset(a,b,sizeof(a))
#define test(flag,value) cout<<flag<<":"<<(value)<<endl
using namespace std;
typedef long long LL;
typedef pair<int,int> PII;
const int INF=0x3f3f3f3f;
const int MOD=1e9+7;
const int MAXN=1e6+5;
const double PI=acos(-1);

LL maxx[MAXN],sum[MAXN];
int a[MAXN];
inline void push_up(int rt)
{
	maxx[rt]=max(maxx[rt<<1],maxx[rt<<1|1]);
	sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
void build(int l,int r, int rt)
{
	if(l==r){
		maxx[rt]=sum[rt]=1ll*a[l];
		return ;
	}
	int m=(l+r)>>1;
	build(l,m,rt<<1);
	build(m+1,r,rt<<1|1);
	push_up(rt);
}

void update(int L,int R,int l,int r,int rt,int p)
{
	if(maxx[rt]<p)
		return;
	if(l==r)
	{
		maxx[rt]%=p;
		sum[rt]%=p;
		return ;
	}
	int m=(l+r)>>1;
	if(m>=L) update(L,R,l,m,rt<<1,p);
	if(m<R)  update(L,R,m+1,r,rt<<1|1,p);
	push_up(rt);
}
void update2(int pos,int l,int r,int rt,int val)
{
	if(l==r&&l==pos)
	{
		sum[rt]=val;
		maxx[rt]=val;
		return;
	}
	int m=(l+r)>>1;
	if(m>=pos) update2(pos,l,m,rt<<1,val);
	if(m<pos)  update2(pos,m+1,r,rt<<1|1,val);
	push_up(rt);
}

LL query(int L,int R,int l, int r,int rt)
{
	if(L<=l&&r<=R) return sum[rt];
	int m=(l+r)>>1;
	LL res=0;
	if(m>=L) res+=query(L,R,l,m,rt<<1);
	if(m<R)  res+=query(L,R,m+1,r,rt<<1|1);
	return res;
}
int main(void)
{
	int n,m;scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
		scanf("%d",a+i);
	build(1,n,1);
	while(m--)
	{
		int type;scanf("%d",&type);
		if(type==1)
		{
			int l,r;scanf("%d%d",&l,&r);
			printf("%lld\n", query(l,r,1,n,1));
		}
		else if(type==2)
		{
			int l,r,x;scanf("%d%d%d",&l,&r,&x);
			update(l,r,1,n,1,x);
		}
		else if(type==3)
		{
			int k,x;scanf("%d%d",&k,&x);
			update2(k,1,n,1,x);
		}
	}
}

猜你喜欢

转载自blog.csdn.net/bnubeginner/article/details/86592815