## bzoj 1798 维护序列seq 线段树

/**************************************************************
Problem: 1798
Language: Pascal
Result: Accepted
Time:24168 ms
Memory:11948 kb
****************************************************************/

type
rec                         =record
left, right, sum        :int64;
m_flag, p_flag          :int64;
end;

var
n, p, m                     :int64;
t                           :array[0..300010] of rec;

procedure build(x,l,r:int64);
var
mid                         :int64;
begin
t[x].left:=l; t[x].right:=r;
t[x].m_flag:=1;
if l=r then
begin
t[x].sum:=t[x].sum mod p;
exit;
end;
with t[x] do mid:=(left+right) div 2;
build(x*2,l,mid); build(x*2+1,mid+1,r);
t[x].sum:=(t[x*2].sum+t[x*2+1].sum) mod p;
end;

procedure m_change(x,l,r,c:int64);
var
mid                         :int64;
cur                         :int64;

begin
if t[x].left<>t[x].right then
begin
if t[x].m_flag<>1 then
begin
cur:=t[x].m_flag;
t[2*x].m_flag:=(t[2*x].m_flag*cur) mod p;
t[2*x].p_flag:=(t[2*x].p_flag*cur) mod p;
t[2*x].sum:=(t[2*x].sum*cur) mod p;
t[2*x+1].m_flag:=(t[2*x+1].m_flag*cur) mod p;
t[2*x+1].p_flag:=(t[2*x+1].p_flag*cur) mod p;
t[2*x+1].sum:=(t[2*x+1].sum*cur) mod p;
t[x].m_flag:=1;
end;
if t[x].p_flag<>0 then
begin
cur:=t[x].p_flag;
t[2*x].p_flag:=(t[2*x].p_flag+cur) mod p;
t[2*x].sum:=(t[2*x].sum+cur*(t[2*x].right-t[2*x].left+1)) mod p;
t[2*x+1].p_flag:=(t[2*x+1].p_flag+cur) mod p;
t[2*x+1].sum:=(t[2*x+1].sum+cur*(t[2*x+1].right-t[2*x+1].left+1)) mod p;
t[x].p_flag:=0;
end;
end;
if (t[x].left=l) and (t[x].right=r) then
begin
t[x].sum:=(t[x].sum*c) mod p;
t[x].p_flag:=(t[x].p_flag*c mod p);
t[x].m_flag:=(t[x].m_flag*c mod p);
exit;
end;
with t[x] do mid:=(left+right) div 2;
if l>mid then m_change(x*2+1,l,r,c) else
if r<=mid then m_change(x*2,l,r,c) else
begin
m_change(x*2,l,mid,c);
m_change(x*2+1,mid+1,r,c);
end;
t[x].sum:=(t[2*x].sum+t[2*x+1].sum) mod p;
end;

procedure p_change(x,l,r,c:int64);
var
mid                         :int64;
cur                         :int64;
begin
if t[x].left<>t[x].right then
begin
if t[x].m_flag<>1 then
begin
cur:=t[x].m_flag;
t[2*x].m_flag:=(t[2*x].m_flag*cur) mod p;
t[2*x].p_flag:=(t[2*x].p_flag*cur) mod p;
t[2*x].sum:=(t[2*x].sum*cur) mod p;
t[2*x+1].m_flag:=(t[2*x+1].m_flag*cur) mod p;
t[2*x+1].p_flag:=(t[2*x+1].p_flag*cur) mod p;
t[2*x+1].sum:=(t[2*x+1].sum*cur) mod p;
t[x].m_flag:=1;
end;
if t[x].p_flag<>0 then
begin
cur:=t[x].p_flag;
t[2*x].p_flag:=(t[2*x].p_flag+cur) mod p;
t[2*x].sum:=(t[2*x].sum+cur*(t[2*x].right-t[2*x].left+1)) mod p;
t[2*x+1].p_flag:=(t[2*x+1].p_flag+cur) mod p;
t[2*x+1].sum:=(t[2*x+1].sum+cur*(t[2*x+1].right-t[2*x+1].left+1)) mod p;
t[x].p_flag:=0;
end;
end;
if (t[x].left=l) and (t[x].right=r) then
begin
t[x].sum:=(t[x].sum+c*(r-l+1)) mod p;
t[x].p_flag:=(t[x].p_flag+c) mod p;
exit;
end;
with t[x] do mid:=(left+right) div 2;
if l>mid then p_change(x*2+1,l,r,c) else
if r<=mid then p_change(x*2,l,r,c) else
begin
p_change(x*2,l,mid,c);
p_change(x*2+1,mid+1,r,c);
end;
t[x].sum:=(t[x*2].sum+t[x*2+1].sum) mod p;
end;

var
mid                         :int64;
cur                         :int64;
begin
if t[x].left<>t[x].right then
begin
if t[x].m_flag<>1 then
begin
cur:=t[x].m_flag;
t[2*x].m_flag:=(t[2*x].m_flag*cur) mod p;
t[2*x].p_flag:=(t[2*x].p_flag*cur) mod p;
t[2*x].sum:=(t[2*x].sum*cur) mod p;
t[2*x+1].m_flag:=(t[2*x+1].m_flag*cur) mod p;
t[2*x+1].p_flag:=(t[2*x+1].p_flag*cur) mod p;
t[2*x+1].sum:=(t[2*x+1].sum*cur) mod p;
t[x].m_flag:=1;
end;
if t[x].p_flag<>0 then
begin
cur:=t[x].p_flag;
t[2*x].p_flag:=(t[2*x].p_flag+cur) mod p;
t[2*x].sum:=(t[2*x].sum+cur*(t[2*x].right-t[2*x].left+1)) mod p;
t[2*x+1].p_flag:=(t[2*x+1].p_flag+cur) mod p;
t[2*x+1].sum:=(t[2*x+1].sum+cur*(t[2*x+1].right-t[2*x+1].left+1)) mod p;
t[x].p_flag:=0;
end;
end;
if (t[x].left=l) and (t[x].right=r) then
begin
exit;
end;
with t[x] do mid:=(left+right) div 2;
end;

procedure init;
begin
build(1,1,n);
end;

procedure main;
var
i                           :longint;
k, l, r, x                  :int64;

begin
for i:=1 to m do
begin
if k=1 then
begin
m_change(1,l,r,x);
end else
if k=2 then
begin
p_change(1,l,r,x);
end else
if k=3 then
begin
end;
end;
end;

begin
init;
main;
end.

赠送对拍器

var
n, m, p                    :longint;
r, l                    :longint;
i                        :longint;
k                        :longint;
begin
randomize;
n:=100000;
m:=100000;
p:=random(1000000000)+1;
writeln(n,' ',p);
for i:=1 to n do write(random(1000000000)+1,' ');
writeln;
writeln(m);
for i:=1 to m do
begin
r:=random(n)+1;
l:=random(r)+1;
k:=random(3)+1;
if k=3 then
writeln(k,' ',l,' ',r) else
writeln(k,' ',l,' ',r,' ',random(10000000000)+1);
end;
end.

posted on 2013-12-11 08:36  BLADEVIL  阅读(362)  评论(1编辑  收藏  举报