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.
原文地址:https://www.cnblogs.com/htfy/p/2394510.html