zoukankan      html  css  js  c++  java
  • 4273_NOIP2015模拟10.28B组_圣章-精灵使的魔法语

    Description

    【背景介绍】
    “魔法???算了吧,这种东西我肯定学不了的啦!”明明是个剑士,却被眼前这位洋洋自得的精灵使——弗洛莉拖出去学魔法,真是个没事找茬的家伙……
    “没事啦。作为一名冒险者会发生很多情况,中毒啦,受伤啦,被咒语束缚之类的,没有魔法就很难办的呀!”她到是好像一副什么都懂的样子,真是令人火大。
    “都说我是个人类了,魔法这种东西学起来很困难的吧!”我只好找个看似靠谱的借口。
    然而,她那不屈不挠的声音又响了起来:“人类虽然与自然的共鸣,也就是魔法的连接较少,但如果认真训练的话还是可以做到的呢!总之,试试看吧!念念咒语之类的!”弗洛莉把魔法书一把拍在了我面前。
    我没兴趣地瞟了一眼,“哼。这种东西我不看也会,伦福萨——密西卡!”才刚刚念完不知道从哪里偷学来的魔法咒语。随即,便听到弗洛莉的一声尖叫,使得整个酒店的人的视线都往这边看来。喂喂喂,别往我这边看啊,我有视线恐惧症啊!!!!况且,我只是把她正在吃的面包的样子变成虫子而已,谁会料到这种情况啊啊啊!!
    “真是的,弗洛莉才是老拖我的后腿呢!”我没好气地笑道……
    “里修!你……”她从牙缝里挤出了一个字。我顿感不妙,见到了那张比魔鬼还可怕的扭曲的面孔。“真是个魔法的天才哪!”她一扫之前不愉快的表情,想我露出大拇指,好像是在夸奖我的样子。
    咦?她竟然没有打我,那真是我福大命大。我这样想着,便一屁股坐在了凳子上,松了口气……
    【题目描述】
    “伦福萨”【即” ( “】和“密西卡”【即” ) “】是两种不同的精灵咒语,已知一个成功的咒语符合如下的规定:
    每一个密西卡之前都可以对应匹配到一个伦福萨,即为一个合法的精灵魔法咒语。
    方便的是,我们将“伦福萨”视为” ( “,“密西卡”视为” ) “,合法的精灵魔法咒语即为一个合法的括号序列。
    如:” ( ( ( ) ) ) “” ( ( ) ( ) ) “” ( ) ( ) ( ) “均为合法的魔法咒语,” ) ( “” ( ) ) ( “” ( ( “均为不合法的魔法咒语。
    现在弗洛莉给我一个长长的“伦福萨”【即” ( “】和“密西卡”【即” ) “】的片段,每次给我一个l和r,让我判断需要在这个片段前最少添多少个“伦福萨”【即” ( “】,以及最少添多少个“密西卡”【即” ) “】可以成为一个合法的魔法咒语,更令人不爽的是,弗洛莉有的时候还会把一个“伦福萨”【即” ( “】变成“密西卡”【即” ) “】,或把一个“密西卡”【即” ) “】变为“伦福萨”【即” ( “】。

    Input

    第一行两个正整数n,m,表示我现在含有的咒语元素(“伦福萨”【即” ( “】和“密西卡”【即” ) “】)的个数以及弗洛莉给我的任务个数,
    第二行包含n个字符(“伦福萨”【即” ( “】或“密西卡”【即” ) “】)表示一开始弗洛莉给我的咒语片段。
    以下m行包括两种任务:
    Change x,表示弗洛莉将位置为x上的咒语片段进行一次变换(原来是“伦福萨”【即” ( “】变为“密西卡”【即” ) “】,原来是“密西卡”【即” ) “】变为“伦福萨”【即” ( “】)。
    Query l r,询问从l到r的区间的片段,在这个片段前最少添上多少个伦福萨”【即” ( “】,在这个片段后最少添上多少个“密西卡”【即” ) “】可以成为合法的魔法序列。

    Output

    每个询问对应一行答案,每行包括两个整数,表示在这个片段前最少添上多少个伦福萨”【即” ( “】,在这个片段后最少添上多少个“密西卡”【即” ) “】可以成为合法的魔法序列。

    Solutions

    线段树模板,注意一下括号的情况即可。

    代码

    type
      arr=record
        l,r:longint;
      end;
    var
      n,m:longint;
      ss:ansistring;
      tree:array [0..1000001] of arr;
    procedure build(p,l,r:longint);
    var
      m:longint;
    begin
      if l=r then
        begin
          if ss[l]='(' then inc(tree[p].l)
                       else inc(tree[p].r);
          exit;
        end;
      m:=(l+r) div 2;
      build(p*2,l,m);
      build(p*2+1,m+1,r);
      if tree[p*2].l>=tree[p*2+1].r then
        begin
          tree[p].r:=tree[p*2].r;
          tree[p].l:=tree[p*2].l-tree[p*2+1].r+tree[p*2+1].l;
        end else
        begin
          tree[p].r:=tree[p*2+1].r-tree[p*2].l+tree[p*2].r;
          tree[p].l:=tree[p*2+1].l;
        end;
    end;
    
    procedure init;
    var
      i:longint;
    begin
      readln(n,m);
      readln(ss);
      build(1,1,n);
    end;
    
    procedure update(p,l,r,t:longint);
    var
      m:longint;
    begin
      if (l=r) then
        begin
          if tree[p].l=1 then begin tree[p].l:=0; tree[p].r:=1; end
                         else begin tree[p].r:=0; tree[p].l:=1; end;
          exit;
        end;
      m:=(l+r) div 2;
      if m>=t then update(p*2,l,m,t);
      if m<t then update(p*2+1,m+1,r,t);
      if tree[p*2].l>=tree[p*2+1].r then
        begin
          tree[p].r:=tree[p*2].r;
          tree[p].l:=tree[p*2].l-tree[p*2+1].r+tree[p*2+1].l;
        end else
        begin
          tree[p].r:=tree[p*2+1].r-tree[p*2].l+tree[p*2].r;
          tree[p].l:=tree[p*2+1].l;
        end;
    end;
    
    procedure check(p,l,r,x,y:longint;var t,k:longint);
    var
      m,oo,pp:longint;
    begin
      if (x<=l) and (r<=y) then
        begin
          t:=tree[p].l; k:=tree[p].r;
          exit;
        end;
      t:=0; k:=0; oo:=0; pp:=0;
      m:=(l+r) div 2;
      if x<=m then check(p*2,l,m,x,y,t,k);
      if m<y then check(p*2+1,m+1,r,x,y,oo,pp);
      if t>=pp then t:=t-pp+oo
               else begin k:=pp-t+k; t:=oo; end;
      exit;
    end;
    
    procedure main;
    var
      i,j,x,y,l,t,k:longint;
      s,so:ansistring;
    begin
      for i:=1 to m do
        begin
          readln(s);
          l:=length(s);
          if s[1]='Q' then
            begin
              j:=6; x:=0;
              while s[j+1]<>' ' do
                begin
                  x:=x*10+ord(s[j+1])-48;
                  inc(j);
                end;
              y:=0; j:=j+1;
              while j<l do
                begin
                  inc(j);
                  y:=y*10+ord(s[j])-48;
                end;
              t:=0; k:=0;
              check(1,1,n,x,y,t,k);
              writeln(k,' ',t);
            end else
            begin
              j:=7; y:=0;
              while j<l do
                begin
                  inc(j);
                  y:=y*10+ord(s[j])-48;
                end;
              update(1,1,n,y);
            end;
        end;
    end;
    
    begin
      init;
      main;
    end.
  • 相关阅读:
    【2019.7.10】树上差分 杂[LCA 倍增][树上差分 点差分 边差分]
    【luogu4145】 上帝造题的七分钟2 / 花神游历各国 [线段树]
    【luogu1198】 [JSOI2008]最大数 [线段树]
    【luogu2783】 有机化学之神偶尔会做作弊 [tarjan 缩点][LCA]
    【luogu3388】 【模板】割点(割顶)[tarjan 割点]
    【luogu2272】 [ZJOI2007]最大半连通子图 [tarjan 缩点][拓扑排序]
    【luogu2194】HXY烧情侣 [tarjan 缩点]
    【luogu3627】 [APIO2009]抢掠计划 [tarjan 缩点][最短路]
    【luogu3398】 仓鼠找sugar [LCA 倍增]
    【luogu2746】 [USACO5.3]校园网Network of Schools [tarjan 缩点]
  • 原文地址:https://www.cnblogs.com/zyx-crying/p/9319494.html
Copyright © 2011-2022 走看看