题目:http://codeforces.com/problemset/problem/438/D
一个数取模n%m,有两种情况、
1.m>n, n%m=n;
2.m<=n, n%m<=n/2;
所以当m>n时,取模操作可以忽略。
每个a[i]最多需要log(a[i])次取模操作变为0,因此我们可以对所有取模进行暴力更新。最多要更新n*log(a[i])次,由于单次更新复杂度为log(n),所以总复杂度为n*logn*log(a[i]).
#include <bits/stdc++.h>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
const int maxn=111111;
int col[maxn<<2];
long long sum[maxn<<2],Max[maxn<<2];
int n,m;
void pushup(int rt){
sum[rt]=sum[rt<<1]+sum[rt<<1|1];
Max[rt]=max(Max[rt<<1],Max[rt<<1|1]);
}
void build(int l,int r,int rt){
if(l==r){
cin>>sum[rt];
Max[rt]=sum[rt];
return;
}
int m=(l+r)>>1;
build(lson);
build(rson);
pushup(rt);
}
int op,l,r,x;
void setvalue(int pos,int val,int l,int r,int rt){
if(l==r){
sum[rt]=Max[rt]=val;
return;
}
int m=(l+r)>>1;
if(pos<=m)setvalue(pos,val,lson);
else setvalue(pos,val,rson);
pushup(rt);
}
void update(int L,int R,int val,int l,int r,int rt){
if(l==r){
sum[rt]%=val;
Max[rt]=sum[rt];
return;
}
int m=(l+r)>>1;
if(L<=m&&Max[rt<<1]>=val)update(L,R,val,lson);
if(R>m&&Max[rt<<1|1]>=val)update(L,R,val,rson);
pushup(rt);
}
long long query(int L,int R,int l,int r,int rt){
if(L<=l&&R>=r)return sum[rt];
long long ans=0;
int m=(l+r)>>1;
if(L<=m)ans+=query(L,R,lson);
if(R>m)ans+=query(L,R,rson);
return ans;
}
int main()
{
// freopen("in","r",stdin);
while(cin>>n>>m){
build(1,n,1);
while(m--){
scanf("%d",&op);
if(op==3){
scanf("%d%d",&l,&x);
setvalue(l,x,1,n,1);
}
else if(op==2){
scanf("%d%d%d",&l,&r,&x);
update(l,r,x,1,n,1);
}
else {
scanf("%d%d",&l,&r);
printf("%I64d\n",query(l,r,1,n,1));
}
}
}
return 0;
}
浙公网安备 33010602011771号