题目大意:
给定一个长度为n的序列,要求能够执行m次下列操作:
1.查询区间[l,r]的和
2.将区间[l,r]的每一个数%=mod
3.修改第x个数为y
操作1,3都是线段树的基本操作,线段树详细知识可以看看这篇大牛的文章 https://www.cnblogs.com/TheRoadToTheGold/p/6254255.html
操作二取模如果一个个模那么复杂度为O(n*m),直接T,我们可以在线段树中同时维护一个最大值,如果一个区间的最大值比取模值要小,就可以不取模,否则的话递归左右子树,继续将每个区间
的最大值与取模值进行比较,一直不断缩小到单点,使需要取模的单点才取模,这样就不会T了
代码如下:
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int inf=1<<30; 4 typedef long long ll; 5 const double pi=acos(-1); 6 const int mod=1e9+7; 7 const int maxn=1e5+7; 8 int n,m;ll ans; 9 struct node{ 10 int l,r,maxx;ll v; 11 }tree[4*maxn]; 12 void modify(int k,int x,int y,int z){ 13 if(tree[k].maxx<z) return ; 14 if(tree[k].l==tree[k].r){ 15 tree[k].v%=z;tree[k].maxx=tree[k].v; 16 return ; 17 } 18 int m=(tree[k].l+tree[k].r)/2; 19 if(x<=m) modify(2*k,x,y,z); 20 if(y>m) modify(2*k+1,x,y,z); 21 tree[k].v=tree[k*2].v+tree[2*k+1].v; 22 tree[k].maxx=max(tree[k*2].maxx,tree[k*2+1].maxx); 23 } 24 void build(int l,int r,int k){ 25 //important 26 tree[k].l=l,tree[k].r=r; 27 if(l==r){ 28 scanf("%d",&tree[k].v); 29 tree[k].maxx=tree[k].v; 30 return ; 31 } 32 int m=(l+r)>>1; 33 build(l,m,k*2); 34 build(m+1,r,k*2+1); 35 tree[k].v=tree[2*k].v+tree[2*k+1].v; 36 tree[k].maxx=max(tree[2*k].maxx,tree[2*k+1].maxx); 37 } 38 void sum(int k,int x,int y){ 39 if(tree[k].l>=x&&tree[k].r<=y){ 40 ans+=tree[k].v; //cout<<111<<endl; 41 return ; 42 } 43 int m=(tree[k].l+tree[k].r)/2; 44 if(x<=m) sum(k*2,x,y); 45 if(y>m) sum(k*2+1,x,y); 46 } 47 void change(int k,int x,int y){ 48 if(tree[k].l==tree[k].r){ 49 tree[k].v=y,tree[k].maxx=y;return; 50 } 51 int m=(tree[k].l+tree[k].r)/2; 52 if(x<=m) change(k*2,x,y); 53 else change(k*2+1,x,y); 54 tree[k].v=tree[2*k].v+tree[2*k+1].v; 55 tree[k].maxx=max(tree[2*k].maxx,tree[2*k+1].maxx); 56 } 57 int main(){ 58 scanf("%d%d",&n,&m); 59 build(1,n,1); 60 while(m--){ 61 int type,x,y,z;scanf("%d%d%d",&type,&x,&y); 62 if(type==1){ 63 ans=0; 64 sum(1,x,y); 65 printf("%lld ",ans); 66 } 67 else if(type==2){ 68 scanf("%d",&z); 69 modify(1,x,y,z); 70 } 71 else if(type==3){ 72 change(1,x,y); 73 } 74 } 75 return 0; 76 }