• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
AC_Artist.zig_zag
然而我依然在补题、
博客园    首页    新随笔    联系   管理    订阅  订阅

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去了)

 

Seq
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 !
posted @ 2013-03-15 23:16  Zig_zag  阅读(312)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3