给一个序列
支持3种操作
1 u v 对于所有i u<=i<=v,输出a[i]的和
2 u v t 对于所有i u<=i<=v a[i]=a[i]%t
3 u v 表示a[u]=v(将v赋值给a[u])
n,q<=1e5 a[i],t,v<=1e9
Input
5 5
1 2 3 4 5
2 3 5 4
3 3 5
1 2 5
2 1 3 3
1 1 3
Output
8
5
提示
对于a%=b,如果a>=b,那么a至少除以2,也就是一个数最多减小log次
取余这个操作只能每个点都操作一次去取余,但可以去剪枝,当mod大于区间最大值的时候可以直接return
#include<stdio.h>
#include<algorithm>
using namespace std;
#define ll long long
#define N 100010
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
struct nomd
{
int l,r;
int mid(){
return (l+r)>>1;
}
}tree[N<<2];
ll maxn[N<<2],sum[N<<2];
void up(int rt)
{
sum[rt]=sum[rt<<1]+sum[rt<<1|1];
maxn[rt]=max(maxn[rt<<1],maxn[rt<<1|1]);
}
//void down(int rt,int m)
//{
// if(add[rt])
// {
// add[rt<<1]=add[rt];
// add[rt<<1|1]=add[rt];
// sum[rt<<1]%=add[rt];
// sum[rt<<1|1]%=add[rt];
// add[rt]=0;
// }
//}
void build(int l,int r,int rt)
{
tree[rt].l=l;tree[rt].r=r;
if(l==r)
{
scanf("%lld",&sum[rt]);
maxn[rt]=sum[rt];
return ;
}
int m=tree[rt].mid();
build(lson);
build(rson);
up(rt);
}
void update1(ll c,int l,int r,int rt)
{
if(maxn[rt]<c)
return;
if(tree[rt].l==tree[rt].r)//原本一直wa在这,因为用了l==r
{
sum[rt]%=c;
maxn[rt]%=c;
return;
}
int m=tree[rt].mid();
if(r<=m) update1(c,l,r,rt<<1);
else if(l>m) update1(c,l,r,rt<<1|1);
else
{
update1(c,l,m,rt<<1);
update1(c,m+1,r,rt<<1|1);
}
up(rt);
}
void update2(int s, int o, ll x) {
if(tree[o].l==tree[o].r && tree[o].l==s) {
sum[o]=x;
maxn[o]=x;
return;
}
int mid=(tree[o].l+tree[o].r)>>1;
if(s<=mid) update2(s,o<<1,x);
else update2(s,o<<1|1,x);
up(o);
}
ll query(int l,int r,int rt)
{
if(tree[rt].l==l&&tree[rt].r==r)
{
return sum[rt];
}
int m=tree[rt].mid();
ll res=0;
if(r<=m) return query(l,r,rt<<1);
else if(l>m) return query(l,r,rt<<1|1);
else
{
return query(l,m,rt<<1)+query(m+1,r,rt<<1|1);
}
}
int main()
{
int n,m;
while(~scanf("%d %d",&n,&m))
{
build(1,n,1);
for(int i=0;i<m;i++)
{
int w;
scanf("%d",&w);
if(w==1)
{
int e, ee;
scanf("%d %d",&e,&ee);
printf("%lld\n",query(e,ee,1));
}
else if(w==3)
{
int e,ee;ll eee;
scanf("%d %lld",&e,&eee);
update2(e,1,eee);
}
else if(w==2)
{
int e,ee;ll eee;
scanf("%d %d %lld",&e,&ee,&eee);
update1(eee,e,ee,1);
}
}
}
return 0;
}