CF438D The Child and Sequence

题面传送门
明显势能线段树。
这里证明一下取模的下界。
对于一个数 x x x,若取模的数 y > x 2 y>\frac{x}{2} y>2x,那么 x % y = x − y < x 2 x\%y=x-y<\frac{x}{2} x%y=xy<2x,若取模的数 y < x 2 y<\frac{x}{2} y<2x,那么 x % y < y < x 2 x\%y<y<\frac{x}{2} x%y<y<2x,则一个数至多取模 l o g n logn logn次就会为 1 1 1
修改至多会增加 l o g n logn logn次取模,也不影响复杂度。
均摊时间复杂度 O ( l o g n ) O(logn) O(logn)
代码实现:

#include<cstdio>
#define max(a,b) ((a)>(b)?(a):(b))
using namespace std;
int n,m,k,x,y,a[100039],z,sx,sum[400039];
long long f[400039];
inline void jianshu(int l,int r,int now){
	if(l==r) {f[now]=a[l];sum[now]=a[l];return;}
	int m=(l+r)>>1;
	jianshu(l,m,now<<1);jianshu(m+1,r,now<<1|1);
	f[now]=f[now<<1]+f[now<<1|1];
	sum[now]=max(sum[now<<1],sum[now<<1|1]);
}
inline long long find(int l,int r,int now){
	if(x<=l&&r<=y)return f[now];
	int m=(l+r)>>1;
	long long fs=0;
	if(x<=m) fs+=find(l,m,now<<1);
	if(y>m) fs+=find(m+1,r,now<<1|1);
	return fs;
}
inline void add(int l,int r,int now){
	if(l==r) {f[now]%=z;sum[now]=f[now];return;}
	int m=(l+r)>>1;
	if(x<=m&&sum[now<<1]>=z) add(l,m,now<<1);
	if(y>m&&sum[now<<1|1]>=z) add(m+1,r,now<<1|1);
	f[now]=f[now<<1]+f[now<<1|1];
	sum[now]=max(sum[now<<1],sum[now<<1|1]);
}
inline void get(int l,int r,int now){
	if(l==r) {f[now]=z,sum[now]=z;return;}
	int m=(l+r)>>1;
	if(x<=m) get(l,m,now<<1);
	else get(m+1,r,now<<1|1);
	f[now]=f[now<<1]+f[now<<1|1];
	sum[now]=max(sum[now<<1],sum[now<<1|1]);
}
int main(){
	register int i;
	scanf("%d%d",&n,&m);
	for(i=1;i<=n;i++) scanf("%d",&a[i]);
	jianshu(1,n,1);
	for(i=1;i<=m;i++){
		scanf("%d",&sx);
		if(sx==1){
			scanf("%d%d",&x,&y);
			printf("%lld\n",find(1,n,1));
		}
		if(sx==2){
			scanf("%d%d%d",&x,&y,&z);
			add(1,n,1);
		}
		if(sx==3){
			scanf("%d%d",&x,&z);
			get(1,n,1);
		}
	}
}//
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值