noi 2007 项链工厂 (bzoj 1493)

http://61.187.179.132/JudgeOnline/problem.php?id=1493

源地址贴的是图。。太麻烦了就不弄过来了、、

 

这道题要是没有R和F的操作就是果果的线段树嘛、、

其实它就是果果的线段树啊。。。

只要把珠子的移动看成是珠子标号的移动就可以完美化归成最基础的线段树实现的区间修改了~~

对于R k的操作把位置1的标号后移k位。对于F的操作记录一个方向,每次取反就行了~~

不过我把判断写得略恶心了。。。

 

还有吐槽下bzoj的歧视pas啊。。本机上表现优秀的程序跑RE了。。。这是第几回了都数不清了、、、

 

program bzoj_1185; 

var a,lazy,lc,rc:array[1..3000000] of longint; 

    n,calc,col,s,t,z:longint; 

//=================================================================== 

procedure push(now:longint); 

begin

  a[now shl 1]:=1; a[now shl 1+1]:=1; 

  lc[now shl 1]:=lazy[now]; rc[now shl 1]:=lazy[now]; 

  lc[now shl 1+1]:=lazy[now]; rc[now shl 1+1]:=lazy[now]; 

  lazy[now shl 1]:=lazy[now]; lazy[now shl 1+1]:=lazy[now]; 

  lazy[now]:=0; 

end; 

//=================================================================== 

procedure ins(be,en,now:longint); 

var mid:longint; 

begin

  if (s<=be) and (en<=t) then 

  begin

    a[now]:=1; lc[now]:=z; rc[now]:=z; 

    lazy[now]:=z; 

    exit; 

  end; 

  if lazy[now]>0 then push(now); 

  mid:=(be+en) shr 1; 

  if s<=mid then ins(be,mid,now shl 1); 

  if t>mid then ins(mid+1,en,now shl 1+1); 

  a[now]:=a[now shl 1]+a[now shl 1+1]; 

  if rc[now shl 1]=lc[now shl 1+1] then dec(a[now]); 

  lc[now]:=lc[now shl 1]; rc[now]:=rc[now shl 1+1]; 

end; 

//=================================================================== 

procedure ask(be,en,now:longint); 

var mid:longint; 

begin

  if (s<=be) and (en<=t) then 

  begin

    inc(calc,a[now]); col:=lazy[now]; 

    exit; 

  end; 

  if lazy[now]>0 then push(now); 

  mid:=(be+en) shr 1; 

  if s<=mid then ask(be,mid,now shl 1); 

  if t>mid then ask(mid+1,en,now shl 1+1); 

  if (s<=mid) and (t>mid) and 

    (rc[now shl 1]=lc[now shl 1+1]) then

      dec(calc); 

end; 

//=================================================================== 

procedure init; 

var i,x,c:longint; 

begin

  readln(n,c); 

  for i:=1 to n do 

  begin

    read(x); 

    s:=i; t:=i; z:=x; ins(1,n,1); 

  end; 

end; 

//=================================================================== 

procedure main; 

var query,ps,pt,x,y,i,tmp,pos,dir,len:longint; 

    co:string; 

begin

  readln(query); pos:=1; dir:=1; 

  for query:=1 to query do

  begin

    readln(co); len:=length(co); 

    if len=1 then 

    begin

      if co='F' then 

        dir:=0-dir else

      if co='C' then 

      begin

        if (lc[1]=rc[1]) and (a[1]>1) then 

          writeln(a[1]-1) else 

            writeln(a[1]); 

      end; 

    end else 

    if co[1]<>'C' then

    begin

      if co[1]='R' then 

      begin i:=3; x:=0; 

        while i<=len do

        begin

          x:=x*10+ord(co[i])-ord('0'); 

          inc(i); 

        end; dec(pos,x*dir); 

        if pos<1 then inc(pos,n); 

        if pos>n then dec(pos,n); 

      end else 

      if co[1]='S' then

      begin x:=0; i:=3; 

        while (i<=len) and (co[i]<>' ') do

        begin

          x:=x*10+ord(co[i])-ord('0'); 

          inc(i); 

        end; y:=0; inc(i); 

        while (i<=len) and (co[i]<>' ') do

        begin

          y:=y*10+ord(co[i])-ord('0'); 

          inc(i); 

        end; 

        s:=pos+dir*x-dir; calc:=0; 

        if s>n then dec(s,n); 

        if s<1 then inc(s,n); 

        t:=s; ask(1,n,1); tmp:=col; 

        ps:=s; pt:=t; 

        s:=pos+dir*y-dir; calc:=0; 

        if s>n then dec(s,n); 

        if s<1 then inc(s,n); 

        t:=s; ask(1,n,1); 

        z:=tmp; ins(1,n,1); 

        z:=col; s:=ps; t:=pt; ins(1,n,1); 

      end else 

      begin x:=0; i:=3; 

        while (i<=len) and (co[i]<>' ') do

        begin

          x:=x*10+ord(co[i])-ord('0'); 

          inc(i); 

        end; y:=0; inc(i); 

        while (i<=len) and (co[i]<>' ') do

        begin

          y:=y*10+ord(co[i])-ord('0'); 

          inc(i); 

        end; z:=0; inc(i); 

        while (i<=len) and (co[i]<>' ') do

        begin

          z:=z*10+ord(co[i])-ord('0'); 

          inc(i); 

        end;  

        ps:=pos+dir*x-dir; 

        if ps<1 then inc(ps,n); 

        if ps>n then dec(ps,n); 

        pt:=pos+dir*y-dir; 

        if pt<1 then inc(pt,n); 

        if pt>n then dec(pt,n); 

        if dir=1 then 

        begin

          if pt>=ps then 

          begin

            s:=ps; t:=pt; ins(1,n,1); 

          end else 

          begin

            s:=ps; t:=n; ins(1,n,1); 

            s:=1; t:=pt; ins(1,n,1); 

          end; 

        end else 

        begin

          if pt<=ps then

          begin

            s:=pt; t:=ps; ins(1,n,1); 

          end else 

          begin

            s:=1; t:=ps; ins(1,n,1); 

            s:=pt; t:=n; ins(1,n,1); 

          end; 

        end; 

      end; 

    end else 

    begin x:=0; i:=4; 

      while (i<=len) and (co[i]<>' ') do

      begin

        x:=x*10+ord(co[i])-ord('0'); 

        inc(i); 

      end; y:=0; inc(i); 

      while (i<=len) and (co[i]<>' ') do

      begin

        y:=y*10+ord(co[i])-ord('0'); 

        inc(i); 

      end; 

      ps:=pos+dir*x-dir; 

      if ps<1 then inc(ps,n); 

      if ps>n then dec(ps,n); 

      pt:=pos+dir*y-dir; 

      if pt<1 then inc(pt,n); 

      if pt>n then dec(pt,n); 

      if dir=1 then 

      begin

        if ps<=pt then

        begin

          s:=ps; t:=pt; calc:=0; 

          ask(1,n,1); writeln(calc); 

        end else 

        begin

          s:=ps; t:=n; calc:=0; 

          ask(1,n,1); tmp:=calc; 

          s:=1; t:=pt; calc:=0; ask(1,n,1); 

          if lc[1]=rc[1] then

            writeln(tmp+calc-1) else

              writeln(tmp+calc); 

        end; 

      end else 

      begin

        if pt<=ps then

        begin

          s:=pt; t:=ps; calc:=0; 

          ask(1,n,1); writeln(calc); 

        end else 

        begin

          s:=1; t:=ps; calc:=0;  

          ask(1,n,1); tmp:=calc; 

          s:=pt; t:=n; calc:=0; 

          ask(1,n,1); 

          if lc[1]=rc[1] then

            writeln(tmp+calc-1) else

              writeln(tmp+calc); 

        end; 

      end; 

    end; 

  end; 

end; 

//=================================================================== 

begin

  init; 

  main; 

end.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值