jzoj P1663【AHOI2009】维护序列

来源:互联网 发布:家具三维设计软件 编辑:程序博客网 时间:2024/06/05 11:21

题目大意:
有长为N的数列,不妨设为a1,a2,…,aN 。有如下三种操作形式:
(1)把数列中的一段数[t,g]全部乘一个值c;
(2)把数列中的一段数[t,g]全部加一个值c;
(3)询问数列中的一段数[t,g]的总和,由于答案可能很大,你只需输出这个数模P的值。

操作:s t g c
1<=n,m<=100000
1≤P≤1000000000
1≤t≤g≤N,0≤c≤1000000000
1<=s<=3

题解:
线段树+双重lazy操作:
题解同上一篇:
http://blog.csdn.net/gx_man_vip/article/details/70230026

var     cp,rp,tree:array [0..1000001] of int64;     sum:array [0..1000001] of int64;     i,j,l,n,m,s,x,y:longint;     ans,k,z:int64;procedure build(p,l,r:longint);var      mid:longint;begin      mid:=(l+r) div 2;      tree[p]:=(sum[r]-sum[l-1]+k) mod k;      rp[p]:=1;      if l>=r then exit;      build(p*2,l,mid);      build(p*2+1,mid+1,r);end;procedure insert(p,l,r,a,b:longint);var      mid,i:longint;begin      mid:=(l+r) div 2;       if (l=a) and (r=b)          then begin                     tree[p * 2]:=(tree[p * 2]*rp[p]+(mid-l+1)*cp[p]) mod k;                     tree[p*2+1]:=(tree[p*2+1]*rp[p]+(r - mid)*cp[p]) mod k;                     rp[p * 2]:=rp[p * 2]*rp[p] mod k;                     rp[p*2+1]:=rp[p*2+1]*rp[p] mod k;                     cp[p * 2]:=(cp[p * 2]*rp[p]+cp[p]) mod k;                     cp[p*2+1]:=(cp[p*2+1]*rp[p]+cp[p]) mod k;                     cp[p]:=0;                     rp[p]:=1;                      if s=1 then                         begin                              tree[p]:=tree[p]*z mod k;                              rp[p]:=rp[p]*z mod k;                         end                         else begin                                   tree[p]:=(tree[p]+(r-l+1)*z) mod k;                                   cp[p]:=(cp[p]+z) mod k;                              end;               end          else begin                     tree[p * 2]:=(tree[p * 2]*rp[p]+(mid-l+1)*cp[p]) mod k;                     tree[p*2+1]:=(tree[p*2+1]*rp[p]+(r - mid)*cp[p]) mod k;                     rp[p * 2]:=rp[p * 2]*rp[p] mod k;                     rp[p*2+1]:=rp[p*2+1]*rp[p] mod k;                     cp[p * 2]:=(cp[p * 2]*rp[p]+cp[p]) mod k;                     cp[p*2+1]:=(cp[p*2+1]*rp[p]+cp[p]) mod k;                     cp[p]:=0;                     rp[p]:=1;                     if b<=mid then insert(p * 2,l,mid,a,b)                               else if a>mid then insert(p*2+1,mid+1,r,a,b)                                             else begin                                                         insert(p * 2,l,mid,a,mid);                                                         insert(p*2+1,mid+1,r,mid+1,b);                                                  end;                     tree[p]:=(tree[p * 2]+tree[p*2+1]) mod k;               end;end;procedure count(p,l,r,a,b:longint);var       mid,i:longint;begin       mid:=(l+r) div 2;       if (l=a) and (r=b)          then ans:=(ans+tree[p]) mod k          else begin                     tree[p * 2]:=(tree[p * 2]*rp[p]+(mid-l+1)*cp[p]) mod k;                     tree[p*2+1]:=(tree[p*2+1]*rp[p]+(r - mid)*cp[p]) mod k;                     rp[p * 2]:=rp[p * 2]*rp[p] mod k;                     rp[p*2+1]:=rp[p*2+1]*rp[p] mod k;                     cp[p * 2]:=(cp[p * 2]*rp[p]+cp[p]) mod k;                     cp[p*2+1]:=(cp[p*2+1]*rp[p]+cp[p]) mod k;                     cp[p]:=0;                     rp[p]:=1;                     if b<=mid then count(p * 2,l,mid,a,b)                               else if a>mid then count(p*2+1,mid+1,r,a,b)                                             else begin                                                         count(p * 2,l,mid,a,mid);                                                         count(p*2+1,mid+1,r,mid+1,b);                                                  end;               end;end;begin     readln(n,k);     for i:=1 to n do         begin              read(sum[i]);              sum[i]:=(sum[i]+sum[i-1]) mod k;         end;     build(1,1,n);     readln(m);     for i:=1 to m do         begin              read(s);              if (s=1) or (s=2) then                 begin                     read(x,y,z);                     insert(1,1,n,x,y);                 end              else if s=3 then                      begin                           ans:=0;                           read(x,y);                           count(1,1,n,x,y);                           writeln(ans);                      end;              readln;         end;end.
1 0
原创粉丝点击