easy CodeForces
阿新 • • 發佈:2019-01-29
給一個序列
支援3種操作
1 u v 對於所有i u<=i<=v,輸出a[i]的和
2 u v t 對於所有i u<=i<=v a[i]=a[i]%t
3 u v 表示a[u]=v(將v賦值給a[u])
n,q<=1e5 a[i],t,v<=1e9
Input
5 5
1 2 3 4 5
2 3 5 4
3 3 5
1 2 5
2 1 3 3
1 1 3
Output
8
5
提示
對於a%=b,如果a>=b,那麼a至少除以2,也就是一個數最多減小log次
取餘這個操作只能每個點都操作一次去取餘,但可以去剪枝,當mod大於區間最大值的時候可以直接return
#include<stdio.h> #include<algorithm> using namespace std; #define ll long long #define N 100010 #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 struct nomd { int l,r; int mid(){ return (l+r)>>1; } }tree[N<<2]; ll maxn[N<<2],sum[N<<2]; void up(int rt) { sum[rt]=sum[rt<<1]+sum[rt<<1|1]; maxn[rt]=max(maxn[rt<<1],maxn[rt<<1|1]); } //void down(int rt,int m) //{ // if(add[rt]) // { // add[rt<<1]=add[rt]; // add[rt<<1|1]=add[rt]; // sum[rt<<1]%=add[rt]; // sum[rt<<1|1]%=add[rt]; // add[rt]=0; // } //} void build(int l,int r,int rt) { tree[rt].l=l;tree[rt].r=r; if(l==r) { scanf("%lld",&sum[rt]); maxn[rt]=sum[rt]; return ; } int m=tree[rt].mid(); build(lson); build(rson); up(rt); } void update1(ll c,int l,int r,int rt) { if(maxn[rt]<c) return; if(tree[rt].l==tree[rt].r)//原本一直wa在這,因為用了l==r { sum[rt]%=c; maxn[rt]%=c; return; } int m=tree[rt].mid(); if(r<=m) update1(c,l,r,rt<<1); else if(l>m) update1(c,l,r,rt<<1|1); else { update1(c,l,m,rt<<1); update1(c,m+1,r,rt<<1|1); } up(rt); } void update2(int s, int o, ll x) { if(tree[o].l==tree[o].r && tree[o].l==s) { sum[o]=x; maxn[o]=x; return; } int mid=(tree[o].l+tree[o].r)>>1; if(s<=mid) update2(s,o<<1,x); else update2(s,o<<1|1,x); up(o); } ll query(int l,int r,int rt) { if(tree[rt].l==l&&tree[rt].r==r) { return sum[rt]; } int m=tree[rt].mid(); ll res=0; if(r<=m) return query(l,r,rt<<1); else if(l>m) return query(l,r,rt<<1|1); else { return query(l,m,rt<<1)+query(m+1,r,rt<<1|1); } } int main() { int n,m; while(~scanf("%d %d",&n,&m)) { build(1,n,1); for(int i=0;i<m;i++) { int w; scanf("%d",&w); if(w==1) { int e, ee; scanf("%d %d",&e,&ee); printf("%lld\n",query(e,ee,1)); } else if(w==3) { int e,ee;ll eee; scanf("%d %lld",&e,&eee); update2(e,1,eee); } else if(w==2) { int e,ee;ll eee; scanf("%d %d %lld",&e,&ee,&eee); update1(eee,e,ee,1); } } } return 0; }