bz1798: [Ahoi2009]Seq
线段树维护区间,比较好像,思路清晰一点的话可以很快地写出来。 维护4个域: add,加标记 mul,乘标记 size,范围大小 key,区间和 考虑4种情况:++,**,*+,+* 前3种显然直接搞一下就行了,在区间上打标记(这里我们设置是打了标记的同时计算区间和)。 先加在乘需要想想,对于一个X+C的式子,如果在外面乘了一个D的话成了D(X+C),去括号变成DX+DC,于是第4种情况既要修改乘标记,又要修改加标记。 注意,乘和加标记代表的都是给区间的每一个数乘或加一个数,所以mul对key的影响是key*mul,而add的影响是key+add,注意永远是先乘再加。 最后就是注意一下数组下标不要越界,数不要撑爆(T_T最烦mod来mod去了)

const maxn=420000; type tt=record key,mul,add,size:int64; end; var t:array[0..maxn]of tt; i,n,m,ll,rr,ms,x,y,z,sign:longint; ans:int64; procedure build(now,l,r:longint); var mid:longint; begin if l=r then begin read(t[now].key); t[now].size:=1; t[now].mul:=1; t[now].add:=0; exit; end; mid:=(l+r)>>1; build(now*2,l,mid); build(now*2+1,mid+1,r); t[now].mul:=1; t[now].add:=0; t[now].key:=(t[now*2].key+t[now*2+1].key) mod ms; t[now].size:=r-l+1; end; procedure down(now:Longint); begin t[now*2].mul:=(t[now*2].mul*t[now].mul) mod ms; t[now*2].add:=((t[now*2].add*t[now].mul) mod ms+t[now].add) mod ms; t[now*2].key:=((t[now*2].key*t[now].mul) mod ms+(t[now].add*t[now*2].size) mod ms) mod ms; t[now*2+1].mul:=(t[now*2+1].mul*t[now].mul) mod ms; t[now*2+1].add:=((t[now*2+1].add*t[now].mul) mod ms+t[now].add) mod ms; t[now*2+1].key:=((t[now*2+1].key*t[now].mul) mod ms+(t[now].add*t[now*2+1].size) mod ms) mod ms; t[now].mul:=1; t[now].add:=0; end; procedure change(now,l,r,x,y:Longint); var mid:Longint; begin if (ll<=l)and(r<=rr) then begin t[now].mul:=(t[now].mul*x) mod ms; t[now].add:=(t[now].add*x) mod ms; t[now].add:=(t[now].add+y) mod ms; t[now].key:=((t[now].key*x) mod ms+(y*t[now].size) mod ms) mod ms; exit; end; down(now); mid:=(l+r)>>1; if mid>=ll then change(now*2,l,mid,x,y); if mid<rr then change(now*2+1,mid+1,r,x,y); t[now].key:=(t[now*2].key+t[now*2+1].key) mod ms; end; function query(now,l,r:Longint):int64; var mid:longint; begin query:=0; if (ll<=l)and(r<=rr) then exit(t[now].key); down(now); mid:=(l+r)>>1; if mid>=ll then query:=(query+query(now*2,l,mid)) mod ms; if mid<rr then query:=(query+query(now*2+1,mid+1,r)) mod ms; end; begin //assign(input,'seq.in'); reset(input); //assign(output,'seq1.out'); rewrite(output); readln(n,ms); build(1,1,n); readln(m); for i:=1 to m do begin read(sign); if sign=1 then begin readln(x,y,z); ll:=x; rr:=y; change(1,1,n,z,0); end else if sign=2 then begin readln(x,y,z); ll:=x; rr:=y; change(1,1,n,1,z); end else begin readln(x,y); ll:=x; rr:=y; ans:=query(1,1,n); writeln(ans); end; end; end.
AC without art, no better than WA !