CF438D The Child and Sequence 線段樹水題
阿新 • • 發佈:2021-07-03
CF438D The Child and Sequence 線段樹水題
取模操作只需要暴力做就可以。我們只需要維護其最大值然後判斷模數是否大於最大值,如果大於,那麼就不用取模了,否則直接往下做。注意到每一個數最多被取模 \(\log\) 次,複雜度最多不超過 \(n\log^210^9\)
\(4\) 秒還是可以過的。
#include<bits/stdc++.h> #define dd double #define ld long double #define ll long long #define int long long #define uint unsigned int #define ull unsigned long long #define N 100010 #define M number using namespace std; const int INF=0x3f3f3f3f; template<typename T> inline void read(T &x) { x=0; int f=1; char c=getchar(); for(;!isdigit(c);c=getchar()) if(c == '-') f=-f; for(;isdigit(c);c=getchar()) x=x*10+c-'0'; x*=f; } template<typename T> inline T Max(T a,T b){ return a<b?b:a; } int n,m,a[N]; struct node{ int sum,maxx; }; struct ST{ node p[N<<4]; inline void pushup(int k){ p[k].sum=p[k*2].sum+p[k*2+1].sum; p[k].maxx=Max(p[k*2].maxx,p[k*2+1].maxx); } inline void build(int k,int l,int r){ if(l==r){p[k].sum=a[l];p[k].maxx=a[l];return;} int mid=(l+r)>>1; build(k*2,l,mid);build(k*2+1,mid+1,r); pushup(k); } inline void change(int k,int l,int r,int x,int val){ if(l==r){p[k].sum=val;p[k].maxx=val;return;} int mid=(l+r)>>1; if(x<=mid) change(k*2,l,mid,x,val); else change(k*2+1,mid+1,r,x,val); pushup(k); } inline int ask_sum(int k,int l,int r,int z,int y){ if(l==z&&r==y){return p[k].sum;} int mid=(l+r)>>1; if(y<=mid) return ask_sum(k*2,l,mid,z,y); else if(z>mid) return ask_sum(k*2+1,mid+1,r,z,y); else return ask_sum(k*2,l,mid,z,mid)+ask_sum(k*2+1,mid+1,r,mid+1,y); }// inline void qumo(int k,int l,int r,int z,int y,int mod){ if(p[k].maxx<mod){return;} if(l==r){p[k].sum%=mod;p[k].maxx=p[k].sum;return;} int mid=(l+r)>>1; if(y<=mid) qumo(k*2,l,mid,z,y,mod); else if(z>mid) qumo(k*2+1,mid+1,r,z,y,mod); else qumo(k*2,l,mid,z,mid,mod),qumo(k*2+1,mid+1,r,mid+1,y,mod); pushup(k); } }; ST st; signed main(){ // freopen("my.in","r",stdin); // freopen("my.out","w",stdout); read(n);read(m); for(int i=1;i<=n;i++) read(a[i]); st.build(1,1,n); for(int i=1;i<=m;i++){ int op;int a,b; read(op);read(a);read(b); if(op==1) printf("%lld\n",st.ask_sum(1,1,n,a,b)); else if(op==2){int x;read(x);st.qumo(1,1,n,a,b,x);} else if(op==3) st.change(1,1,n,a,b); } return 0; }