Codeforces 438D The Child and Sequence
阿新 • • 發佈:2017-10-02
stdout 如果 scanf pri () algorithm i++ main 一個
題意:給定一個n個數的序列,完成以下3個操作:
1.給定區間求和
2.給定區間對x取模
3.單點修改
對一個數取模,這個數至少折半。於是我們記一個最大值max,如果x>max則不做處理。
#include<stdio.h> #include<algorithm> using namespace std; #define MAXN 1000000+10 typedef long long LL; struct tree{LL mx,sum;}tr[MAXN<<1]; int n,m; LL a[MAXN]; void build(int k,intl,int r){ if(l==r){ tr[k].mx=tr[k].sum=a[l]; return; } int mid=(l+r)>>1; build(k<<1,l,mid); build(k<<1|1,mid+1,r); tr[k].mx=max(tr[k<<1].mx,tr[k<<1|1].mx); tr[k].sum=tr[k<<1].sum+tr[k<<1|1].sum; } LL sum(int k,intl,int r,int L,int R){ if(l>=L&&r<=R)return tr[k].sum; int mid=(l+r)>>1; if(R<=mid)return sum(k<<1,l,mid,L,R); else if(L>mid)return sum(k<<1|1,mid+1,r,L,R); else return sum(k<<1,l,mid,L,R)+sum(k<<1|1,mid+1,r,L,R); tr[k].mx=max(tr[k<<1].mx,tr[k<<1|1].mx); tr[k].sum=tr[k<<1].sum+tr[k<<1|1].sum; } void update(int k,int l,int r,int t,LL x){ if(l==t&&r==t){ tr[k].mx=tr[k].sum=x; return; } int mid=(l+r)>>1; if(t<=mid)update(k<<1,l,mid,t,x); if(t>mid)update(k<<1|1,mid+1,r,t,x); tr[k].mx=max(tr[k<<1].mx,tr[k<<1|1].mx); tr[k].sum=tr[k<<1].sum+tr[k<<1|1].sum; } void mod(int k,int l,int r,int L,int R,LL x){ if(tr[k].mx<x)return; if(l==r){ tr[k].mx%=x; tr[k].sum%=x; return; } int mid=(l+r)>>1; if(R<=mid)mod(k<<1,l,mid,L,R,x); else if(L>mid)mod(k<<1|1,mid+1,r,L,R,x); else mod(k<<1,l,mid,L,R,x),mod(k<<1|1,mid+1,r,L,R,x); tr[k].mx=max(tr[k<<1].mx,tr[k<<1|1].mx); tr[k].sum=tr[k<<1].sum+tr[k<<1|1].sum; } int main(){ //freopen("mod.in","r",stdin); //freopen("mod.out","w",stdout); scanf("%d%d",&n,&m); for(int i=1;i<=n;i++)scanf("%I64d",&a[i]); build(1,1,n); while(m--){ int opt; scanf("%d",&opt); if(opt==1){ int l,r; scanf("%d%d",&l,&r); printf("%I64d\n",sum(1,1,n,l,r)); } if(opt==2){ int l,r;LL x; scanf("%d%d%I64d",&l,&r,&x); mod(1,1,n,l,r,x); } if(opt==3){ int k;LL y; scanf("%d%I64d",&k,&y); update(1,1,n,k,y); } } return 0; }
Codeforces 438D The Child and Sequence