圣章-精灵使的魔法语【线段树】

本文介绍了一个括号匹配问题,并通过线段树实现高效查询与更新操作。通过对线段树进行优化,实现了O(nlogn)的时间复杂度,解决了区间括号匹配的问题。

题目大意:

给出一个由“(”和“)”组成的字符串,以及mm种要求:

  1. Change xx,将第x位的括号改变方向。
    • QueryQuery ll r,输出若要让llr之间的括号全部匹配,要在左边加入多少个“(”,右边加上多少个“)”。
    • InputInput

      4 3
      )()(
      Query 1 4
      Change 3
      Query 1 4

      OutputOutput

      1 1
      1 3
      

      思路:

      好难啊这道题。。。
      重点是只有O(n)O(n)O(nlogn)O(nlogn)才能过!!!
      改了我一个下午++晚上1小时,共耗时6.5hour
      还有,这道题卡常,还得优化一下才能过。。。


      这道题要我们区间修改和查询,自然是线段树。
      一棵普通的线段树长这个样子:
      这里写图片描述
      我们把这棵线段树的叶子节点赋值为s[i]s[i](即输入的括号串的每一个字符)。拿样例来说,就是这个样子:
      这里写图片描述
      再将这棵树合并
      这里写图片描述
      把红色部分的可以匹配的去掉
      这里写图片描述
      就可以求出每个区间需要匹配多少号啦!
      那么对于ChangeChange操作,我们可以递归找到需要改变的点
      这里写图片描述
      将这个字符改变
      这里写图片描述
      递归回去
      这里写图片描述
      就可以啦!
      这个过程细节十分多,思路必须特备清晰!


      代码:

      #include <cstdio>
      #include <iostream>
      #include <cstring>
      #define fre(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout);
      using namespace std;
      
      int n,m,x,y,t,L,R;
      char c[7],s[300001];
      
      struct node
      {
          int l,r,lnum,rnum;
      }tree[800001];
      
      void make(int x)  //建树
      {
          if (tree[x].r==tree[x].l)  //叶子节点
          {
              if (s[tree[x].l-1]==')') tree[x].lnum=1;
              else tree[x].rnum=1;  //赋值字符
              return;
          }
          int mid=(tree[x].l+tree[x].r)/2;
          tree[x*2].l=tree[x].l;
          tree[x*2].r=mid;
          tree[x*2+1].l=mid+1;
          tree[x*2+1].r=tree[x].r;  //给子节点赋值
          make(x*2);
          make(x*2+1);  //继续建图
          tree[x].lnum=tree[x*2].lnum+max(0,tree[x*2+1].lnum-tree[x*2].rnum);
          tree[x].rnum=tree[x*2+1].rnum+max(0,tree[x*2].rnum-tree[x*2+1].lnum);  //求出每边必须增加几个括号
          return;
      }
      
      void find(int x,int l,int r)  //Query操作
      {
          if (l==tree[x].l&&r==tree[x].r)  //找到这部分
          {
              L=tree[x].lnum;
              R=tree[x].rnum;  //赋值
              return;
          }
          if (tree[x].l==tree[x].r) return; //叶子节点
          int mid=(tree[x].l+tree[x].r)/2;
          if (r<=mid)  //完全在左边
          {
              find(x*2,l,r);
              return;
          }
          if (l>mid)  //完全在右边
          {
              find(x*2+1,l,r);
              return;
          }
          find(x*2,l,mid);  //两边都有
          int ll=L,rr=R;
          find(x*2+1,mid+1,r);
          int lll=L,rrr=R;
          L=ll+max(0,lll-rr);
          R=rrr+max(0,rr-lll);
          return;
      }
      
      void makes(int x,int p)  //Change操作
      {
          if (tree[x].l==p&&tree[x].r==p)  //找到更改点
          {
              tree[x].lnum=1-tree[x].lnum;
              tree[x].rnum=1-tree[x].rnum;  //更改(1变0,0变1)
              return;
          }
          if (tree[x].l==tree[x].r) return;  //叶子节点
          int mid=(tree[x].l+tree[x].r)/2;
          if (p<=mid) makes(x*2,p);
           else makes(x*2+1,p);  //log(n)找出更改点
          tree[x].lnum=tree[x*2].lnum+max(0,tree[x*2+1].lnum-tree[x*2].rnum);
          tree[x].rnum=tree[x*2+1].rnum+max(0,tree[x*2].rnum-tree[x*2+1].lnum);
          return;
      }
      
      int main()
      {
          fre(elf);
          scanf("%d%d",&n,&m);
          scanf("%s",s);
          tree[1].l=1;
          tree[1].r=n;    
          make(1);  //建图
          for (int i=1;i<=m;i++)
          {
              scanf("%s",c);
              if (c[0]=='Q')
              {
                  L=R=0;
                  scanf("%d%d",&x,&y);
                  find(1,x,y);
                  printf("%d %d\n",L,R);
              }
              else
              {
                  scanf("%d",&x);
                  makes(1,x);
              }
          }
          return 0;
      }

(Mathcad+Simulink仿真)基于扩展描述函数法的LLC谐振变换器小信号分析设计内容概要:本文围绕“基于扩展描述函数法的LLC谐振变换器小信号分析设计”展开,结合Mathcad与Simulink仿真工具,系统研究LLC谐振变换器的小信号建模方法。重点利用扩展描述函数法(Extended Describing Function Method, EDF)对LLC变换器在非线性工作条件下的动态特性进行线性化近似,建立适用于频域分析的小信号模型,并通过Simulink仿真验证模型准确性。文中详细阐述了建模理论推导过程,包括谐振腔参数计算、开关网络等效处理、工作模态分析及频响特性提取,最后通过仿真对比验证了该方法在稳定性分析与控制器设计中的有效性。; 适合人群:具备电力电子、自动控制理论基础,熟悉Matlab/Simulink和Mathcad工具,从事开关电源、DC-DC变换器或新能源变换系统研究的研究生、科研人员及工程技术人员。; 使用场景及目标:①掌握LLC谐振变换器的小信号建模难点与解决方案;②学习扩展描述函数法在非线性系统线性化中的应用;③实现高频LLC变换器的环路补偿与稳定性设计;④结合Mathcad进行公式推导与参数计算,利用Simulink完成动态仿真验证。; 阅读建议:建议读者结合Mathcad中的数学推导与Simulink仿真模型同步学习,重点关注EDF法的假设条件与适用范围,动手复现建模步骤和频域分析过程,以深入理解LLC变换器的小信号行为及其在实际控制系统设计中的应用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值