您的位置:首页 > 产品设计 > UI/UE

codeforces 438D The Child and Sequence

2017-08-01 11:54 218 查看
题面:codeforces438D

正解:线段树。

这题好像是$picks$出的题,然后无限弱化才上的$cf$。。

区间取模,每个数取模以后至少$/2$,所以暴力搞即可。

证明:若$p<x/2$,那么$x \ mod \ p<x/2$;若$p>x/2$,那么$ x \ mod \ p=x-p<x/2$。

维护一个区间最大值,如果$<p$那么就直接退出,否则把这个区间递归做再取模。

//It is made by wfj_2048~
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <vector>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#define N (200010)
#define ls (x<<1)
#define rs (x<<1|1)
#define il inline
#define RG register
#define ll long long

using namespace std;

int mx[N<<2],a
,n,m;
ll sum[N<<2];

il int gi(){
RG int x=0,q=1; RG char ch=getchar();
while ((ch<'0' || ch>'9') && ch!='-') ch=getchar();
if (ch=='-') q=-1,ch=getchar();
while (ch>='0' && ch<='9') x=x*10+ch-48,ch=getchar();
return q*x;
}

il void pushup(RG int x){
sum[x]=sum[ls]+sum[rs],mx[x]=max(mx[ls],mx[rs]); return;
}

il void build(RG int x,RG int l,RG int r){
if (l==r){ sum[x]=mx[x]=a[l]; return; } RG int mid=(l+r)>>1;
build(ls,l,mid),build(rs,mid+1,r),pushup(x); return;
}

il void update(RG int x,RG int l,RG int r,RG int p,RG int v){
if (l==r){ sum[x]=mx[x]=v; return; } RG int mid=(l+r)>>1;
p<=mid?update(ls,l,mid,p,v):update(rs,mid+1,r,p,v);
pushup(x); return;
}

il void updatemod(RG int x,RG int l,RG int r,RG int xl,RG int xr,RG int v){
if (l==r){ sum[x]%=v,mx[x]%=v; return; }
if (mx[x]<v) return; RG int mid=(l+r)>>1;
if (xr<=mid) updatemod(ls,l,mid,xl,xr,v);
else if (xl>mid) updatemod(rs,mid+1,r,xl,xr,v);
else updatemod(ls,l,mid,xl,mid,v),updatemod(rs,mid+1,r,mid+1,xr,v);
pushup(x); return;
}

il ll query(RG int x,RG int l,RG int r,RG int xl,RG int xr){
if (xl<=l && r<=xr) return sum[x]; RG int mid=(l+r)>>1;
if (xr<=mid) return query(ls,l,mid,xl,xr);
else if (xl>mid) return query(rs,mid+1,r,xl,xr);
else return query(ls,l,mid,xl,mid)+query(rs,mid+1,r,mid+1,xr);
}

int main(){
#ifndef ONLINE_JUDGE
freopen("438D.in","r",stdin);
freopen("438D.out","w",stdout);
#endif
n=gi(),m=gi();
for (RG int i=1;i<=n;++i) a[i]=gi(); build(1,1,n);
for (RG int i=1,op,l,r,x,k;i<=m;++i){
op=gi();
if (op==1) l=gi(),r=gi(),printf("%I64d\n",query(1,1,n,l,r));
if (op==2) l=gi(),r=gi(),x=gi(),updatemod(1,1,n,l,r,x);
if (op==3) k=gi(),x=gi(),update(1,1,n,k,x);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: