标签:
At the children‘s day, the child came to Picks‘s house, and messed his house up. Picks was angry at him. A lot of important things were lost, in particular the favorite sequence of Picks.
Fortunately, Picks remembers how to repair the sequence. Initially he should create an integer array a[1], a[2], ..., a[n]. Then he should perform a sequence of m operations. An operation can be one of the following:
Can you help Picks to perform the whole sequence of operations?
The first line of input contains two integer: n, m (1 ≤ n, m ≤ 105). The second line contains n integers, separated by space:a[1], a[2], ..., a[n] (1 ≤ a[i] ≤ 109) — initial value of array elements.
Each of the next m lines begins with a number type .
For each operation 1, please print a line containing the answer. Notice that the answer may exceed the 32-bit integer.
5 5
1 2 3 4 5
2 3 5 4
3 3 5
1 2 5
2 1 3 3
1 1 3
8
5
题意:
操作1:l,r 求l到r之间的区间和
操作2:l,r,c 将l到r之间的数分别取模x
操作3:l,r 讲a[l]改成r;
题解:
线段树的区间操作
对于去摸:我们设置一个区间段最大值,要取得模要是大于这个最大则之间退出
这就是优化
///1085422276 #include<bits/stdc++.h> using namespace std ; typedef long long ll; #define mem(a) memset(a,0,sizeof(a)) #define meminf(a) memset(a,127,sizeof(a)); #define inf 1000000007 #define mod 1000000007 inline ll read() { ll x=0,f=1;char ch=getchar(); while(ch<‘0‘||ch>‘9‘){ if(ch==‘-‘)f=-1;ch=getchar(); } while(ch>=‘0‘&&ch<=‘9‘){ x=x*10+ch-‘0‘;ch=getchar(); }return x*f; } //************************************************ const int maxn=100000+5; int a[maxn],n,m,q; struct ss{ int l,r; ll v,sum,tag; }tr[maxn*5]; void build(int k,int s,int t) { tr[k].l=s;tr[k].r=t; tr[k].v=0;tr[k].tag=0;tr[k].sum=0; if(s==t){ tr[k].sum=a[s]; tr[k].v=a[s]; return ; } int mid=(s+t)>>1; build(k<<1,s,mid); build(k<<1|1,mid+1,t); tr[k].sum=tr[k<<1].sum+tr[k<<1|1].sum; tr[k].v=max(tr[k<<1].v,tr[k<<1|1].v); } ll ask(int k,int s,int t) { if(tr[k].l==s&&tr[k].r==t){ return tr[k].sum; } int mid=(tr[k].l+tr[k].r)>>1; ll ret=0; if(t<=mid)ret= ask(k<<1,s,t); else if(s>mid)ret= ask(k<<1|1,s,t); else { ret=(ask(k<<1,s,mid)+ask(k<<1|1,mid+1,t)); } tr[k].sum=tr[k<<1].sum+tr[k<<1|1].sum; tr[k].v=max(tr[k<<1].v,tr[k<<1|1].v); return ret; } void modify(int k,int s,int t,ll c) { if(tr[k].v<c)return ; if(tr[k].l==tr[k].r){ tr[k].sum%=c; tr[k].v%=c; return ; } int mid=(tr[k].l+tr[k].r)>>1; if(t<=mid)modify(k<<1,s,t,c); else if(s>mid)modify(k<<1|1,s,t,c); else { modify(k<<1,s,mid,c);modify(k<<1|1,mid+1,t,c); } tr[k].sum=tr[k<<1].sum+tr[k<<1|1].sum; tr[k].v=max(tr[k<<1].v,tr[k<<1|1].v); } void update(int k,int x,int c) { if(tr[k].l==x&&tr[k].r==x){ tr[k].sum=c; tr[k].v=c; return; } int mid=(tr[k].l+tr[k].r)>>1; if(x<=mid)update(k<<1,x,c); else { update(k<<1|1,x,c); } tr[k].sum=tr[k<<1].sum+tr[k<<1|1].sum; tr[k].v=max(tr[k<<1].v,tr[k<<1|1].v); } int main(){ n=read();m=read(); for(int i=1;i<=n;i++){ scanf("%d",&a[i]); }build(1,1,n);int x,y;ll c; for(int i=1;i<=m;i++){ scanf("%d",&q); if(q==1){ scanf("%d%d",&x,&y); printf("%I64d\n",ask(1,x,y)); } else if(q==2){ scanf("%d%d%I64d",&x,&y,&c); modify(1,x,y,c); } else { scanf("%d%d",&x,&y); update(1,x,y); } } return 0; }
Codeforces Round #250 (Div. 1) D. The Child and Sequence 线段树 区间求和+点修改+区间取模
标签:
原文地址:http://www.cnblogs.com/zxhl/p/4924714.html