题目: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; }
时间: 2024-09-30 00:43:48