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.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章