1. 程式人生 > >Codeforces 438D The Child and Sequence

Codeforces 438D The Child and Sequence

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,int
l,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,int
l,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