CodeForces - 438D(線段樹+剪枝)
阿新 • • 發佈:2020-07-16
1.區間求和 2.區間取模 3.單點修改
線段樹,區間取模加一個剪枝:區間最大值<mod,不修改。其他單點取模
#include <bits/stdc++.h> using namespace std; #define debug printf("bug!!!\n"); typedef long long ll; const int MAXN=1e5+10; const ll MOD=1e9+7; ll tree[MAXN*4]; ll lazy[MAXN*4]; ll a[MAXN]; ll tree_max[MAXN*4]; void build(int p,int l,int r){ if(l==r){ tree[p]=a[l]; tree_max[p]=a[l]; return ; } int mid=(l+r)>>1; build(p<<1,l,mid); build(p<<1|1,mid+1,r); tree[p]=tree[p<<1]+tree[p<<1|1]; tree_max[p]=max(tree_max[p<<1],tree_max[p<<1|1]); } void update(int p,int l,int r,int x,int c){ if(l==r){ tree[p]=c; tree_max[p]=c; return; } int mid=(l+r)>>1; if(x<=mid)update(p<<1,l,mid,x,c); if(x>mid)update(p<<1|1,mid+1,r,x,c); tree[p]=tree[p<<1]+tree[p<<1|1]; tree_max[p]=max(tree_max[p<<1],tree_max[p<<1|1]); } void update_mod(int p,int l,int r,int L,int R,int x){ if(L<=l && r<=R){ if(tree_max[p]<x){ return; } if(l==r){ tree[p]%=x; tree_max[p]%=x; return; } } int mid=(l+r)>>1; if(L<=mid)update_mod(p<<1,l,mid,L,R,x); if(R>mid)update_mod(p<<1|1,mid+1,r,L,R,x); tree[p]=tree[p<<1]+tree[p<<1|1]; tree_max[p]=max(tree_max[p<<1],tree_max[p<<1|1]); } ll query(int p,int l,int r,int L,int R){ if(L<=l && r<=R){ return tree[p]; } int mid=(l+r)>>1; ll res=0; if(L<=mid)res+=query(p<<1,l,mid,L,R); if(R>mid)res+=query(p<<1|1,mid+1,r,L,R); return res; } int main(){ int n,m; cin>>n>>m; for(int i=1;i<=n;i++)cin>>a[i]; build(1,1,n); while(m--){ int op; cin>>op; if(op==1){ int l,r; cin>>l>>r; cout<<query(1,1,n,l,r)<<endl; } else if(op==2){ int l,r,x; cin>>l>>r>>x; update_mod(1,1,n,l,r,x); } else{ int x,c; cin>>x>>c; update(1,1,n,x,c); } } return 0; }