bzoj1798 AHOI2009 行星序列 seq
/************************************************************** Problem: 1798 User: HTwood Language: Pascal Result: Accepted Time:14892 ms Memory:13116 kb ****************************************************************/ program seq; Function min(a,b:longint):longint; begin if a<b then exit(a) else exit(b); end; Function max(a,b:longint):longint; begin if a>b then exit(a) else exit(b); end; Type rec=record l,r:longint; mul,add,sum:int64; end; Var f:array[0..400000] of rec; a:array[0..100000] of longint; n,m,x,opt,t,g,c,top,i:longint; Procedure relax(P:longint); begin if p*2+1>top then begin f[p].mul:=1; f[p].add:=0; exit; end; f[p*2].sum:=(f[p*2].sum*f[p].mul+(f[p*2].r-f[p*2].l+1)*f[p].add) mod x; f[p*2+1].sum:=(f[p*2+1].sum*f[p].mul+(f[p*2+1].r-f[p*2+1].l+1)*f[p].add) mod x; f[p*2].mul:=f[p*2].mul*f[p].mul mod x; f[p*2].add:=f[p*2].add*f[p].mul mod x+f[p].add mod x; f[p*2+1].mul:=f[p*2+1].mul*f[p].mul mod x; f[p*2+1].add:=f[p*2+1].add*f[p].mul mod x+f[p].add mod x; f[p].mul:=1;f[p].add:=0; end; Procedure init(var p:rec;pl,pr:longint); begin p.l:=pl;p.r:=pr; p.add:=0;p.mul:=1; p.sum:=0; end; Procedure build(p:longint); var mid:longint; begin if p>top then top:=p; if f[p].l=f[p].r then begin f[p].sum:=a[f[p].l] mod x;exit;end; mid:=(f[p].l+f[p].r) div 2; init(f[p*2],f[p].l,mid); init(f[p*2+1],mid+1,f[p].r); build(p*2); build(p*2+1); f[p].sum:=(f[p*2].sum+f[p*2+1].sum) mod x; end; Procedure Change(P,pl,pr,g,c:longint); var mid:longint; begin Relax(p); if (f[p].l=pl) and (f[p].r=pr) then begin f[p].sum:=(f[p].sum*g+c*(f[p].r-f[p].l+1)) mod x; f[p].mul:=(f[p].mul*g) mod x; f[p].add:=(f[p].add*g+c) mod x; exit; end; mid:=(f[p].l+f[p].r) div 2; if pl<=mid then change(p*2,pl,min(pr,mid),g,c); if pr>mid then change(p*2+1,max(pl,mid+1),pr,g,c); f[p].sum:=(f[p*2].sum+f[p*2+1].sum) mod x; end; Function getsum(P,pl,pr:longint):int64; var mid:longint; begin relax(P); if (f[p].l=pl) and (f[p].r=pr) then exit(f[p].sum mod x); Getsum:=0; mid:=(f[p].l+f[p].r) div 2; if pl<=mid then inc(getsum,getsum(p*2,pl,min(mid,pr))); if pr>mid then inc(getsum,getsum(p*2+1,max(mid+1,pl),pr)); getsum:=getsum mod x; end; begin readln(n,x); for i:=1 to n do read(a[i]); readln; fillchar(f,sizeof(f),0); top:=1; init(f[1],1,n); Build(1); readln(m); for i:=1 to m do begin read(opt); case opt of 1: begin readln(t,g,c); Change(1,t,g,c,0); end; 2: begin readln(t,g,c); Change(1,t,g,1,c); end; 3: begin readln(t,g); writeln(getsum(1,t,g) mod x); end; end; end; end.