题意:给一串括号,有2个操作,1。翻转某个括号。2。查询某段区间内化简后第k个括号是在原序列中的位置。1 ≤ N,Q ≤ 200000.

题解:

可以知道,化简后的序列一定是)))((((这种形式的。

线段树每个节点就存对应区间内化简后的ls也就是)的数量,rs也就是(的数量。

然后我先把区间[l,r]找出来合并一遍,找出第k个是哪一种扩号。

问题转化为找区间[l,r]中的第kk个左扩号或者右括号。

我们可以发现,如果是)这种括号,区间从左到右合并的时候是单调不减的。

同理,(这种括号,区间从右往左合并的时候也是单调不减的。

然后我是变成从左往右的第kk个),或者从右往左的第kk个(。

[l,r]这个区间在线段树里可能由若干个区间组合而来,我们就根据左右括号的不同从左或从右合一遍,恰好遇到第kk个的时候就进去找。这个找就简单很多,因为它就是在线段树上走一遍的。

细节挺多的。

 #include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std; const int N=;
int n,m,tl,cl,c[N];
char s[N];
struct node{
int l,r,lc,rc,ls,rs;// ls ))) rs (((
}t[*N]; int maxx(int x,int y){return x>y ? x:y;} node upd(node x,node lc,node rc)
{
x.ls=lc.ls;
x.rs=rc.rs;
int sum=rc.ls-lc.rs;
if(sum>) x.ls+=sum;
else x.rs+=-sum;
// x.ls=maxx(0,lc.ls+rc.ls-lc.rs);
// x.rs=maxx(0,rc.rs+lc.rs-rc.ls);
return x;
} int bt(int l,int r)
{
int x=++tl;
t[x].l=l;t[x].r=r;
t[x].lc=t[x].rc=;
t[x].ls=t[x].rs=;
if(l<r)
{
int mid=(l+r)/;
t[x].lc=bt(l,mid);
t[x].rc=bt(mid+,r);
int lc=t[x].lc,rc=t[x].rc;
t[x]=upd(t[x],t[lc],t[rc]);
}
else
{
if(s[l]==')') t[x].ls=;
else t[x].rs=;
}
return x;
} void change(int x,int p)
{
if(t[x].l==t[x].r) {swap(t[x].ls,t[x].rs);return ;}
int lc=t[x].lc,rc=t[x].rc,mid=(t[x].l+t[x].r)/;
if(p<=mid) change(lc,p);
else change(rc,p);
t[x]=upd(t[x],t[lc],t[rc]);
} void query(int x,int l,int r)
{
if(t[x].l==l && t[x].r==r) {c[++cl]=x;return;}
int lc=t[x].lc,rc=t[x].rc,mid=(t[x].l+t[x].r)/;
if(r<=mid) query(lc,l,r);
else if(l>mid) query(rc,l,r);
else
{
query(lc,l,mid);
query(rc,mid+,r);
}
} int fd(int x,int k,int tmp)
{
if(t[x].l==t[x].r) return t[x].l;
int lc=t[x].lc,rc=t[x].rc;
if(tmp==)
{
if(t[lc].ls>=k) return fd(lc,k,tmp);
return fd(rc,k-t[lc].ls+t[lc].rs,tmp);
}
else
{
if(t[rc].rs>=k) return fd(rc,k,tmp);
return fd(lc,k-t[rc].rs+t[rc].ls,tmp);
}
} int main()
{
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
scanf("%s",s+);
tl=;bt(,n);
for(int i=;i<=m;i++)
{
int tmp,x,l,r,k,ans;
scanf("%d",&tmp);
if(tmp==)
{
scanf("%d",&x);
change(,x);
}
else
{
scanf("%d%d%d",&l,&r,&k);
cl=;query(,l,r);
node now=t[c[]];
for(int j=;j<=cl;j++) now=upd(now,now,t[c[j]]);
if(now.ls+now.rs<k) {printf("-1\n");continue;}
if(now.ls>=k)
{
node p0=t[c[]],p1;
if(p0.ls>=k) ans=fd(c[],k,);
else
{
for(int j=;j<=cl;j++)
{
p1=upd(p1,p0,t[c[j]]);
if(p1.ls>=k)
{
ans=fd(c[j],k-p0.ls+p0.rs,);
break;
}
p0=p1;
}
}
}
else
{
k=now.ls+now.rs-k+;
node p0=t[c[cl]],p1;
if(p0.rs>=k) ans=fd(c[cl],k,);
else
{
for(int j=cl-;j>=;j--)
{
p1=upd(p1,t[c[j]],p0);
if(p1.rs>=k) {ans=fd(c[j],k-p0.rs+p0.ls,);break;}
p0=p1;
}
}
}
printf("%d\n",ans);
}
}
}
return ;
}

【hdu5217-括号序列】线段树的更多相关文章

  1. bzoj 1095 [ZJOI2007]Hide 捉迷藏(括号序列+线段树)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1095 [题意] 给定一棵树,树上颜色或白或黑而且可以更改,多个询问求最远黑点之间的距离 ...

  2. 【BZOJ】1095: [ZJOI2007]Hide 捉迷藏 括号序列+线段树

    [题目]BZOJ 1095 [题意]给定n个黑白点的树,初始全为黑点,Q次操作翻转一个点的颜色,或询问最远的两个黑点的距离,\(n \leq 10^5,Q \leq 5*10^5\). [算法]括号序 ...

  3. BZOJ1095 [ZJOI2007] Hide 捉迷藏 (括号序列 + 线段树)

    题意 给你一颗有 \(n\) 个点的树 , 共有 \(m\) 次操作 有两种类别qwq 将树上一个点染黑/白; 询问树上最远的两个黑点的距离. \((n \le 200000, m ≤500000)\ ...

  4. 【BZOJ 1095】 1095: [ZJOI2007]Hide 捉迷藏 (括号序列+线段树)

    1095: [ZJOI2007]Hide 捉迷藏 Description 捉迷藏 Jiajia和Wind是一对恩爱的夫妻,并且他们有很多孩子.某天,Jiajia.Wind和孩子们决定在家里玩捉迷藏游戏 ...

  5. Snacks HDU 5692 dfs序列+线段树

    Snacks HDU 5692 dfs序列+线段树 题意 百度科技园内有n个零食机,零食机之间通过n−1条路相互连通.每个零食机都有一个值v,表示为小度熊提供零食的价值. 由于零食被频繁的消耗和补充, ...

  6. hdu 4521 小明系列问题——小明序列 线段树+二分

    小明系列问题——小明序列 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others) Pro ...

  7. BZOJ 4034 树上操作(树的欧拉序列+线段树)

    刷个清新的数据结构题爽一爽? 题意: 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三种: 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x ...

  8. 【Foreign】划分序列 [线段树][DP]

    划分序列 Time Limit: 20 Sec  Memory Limit: 256 MB Description Input Output 仅一行一个整数表示答案. Sample Input 9 4 ...

  9. BZOJ 1798 AHOI2009 Seq 维护序列 线段树

    题目大意:维护一个序列,提供三种操作: 1.将区间中每个点的权值乘上一个数 2.将区间中每个点的权值加上一个数 3.求一段区间的和对p取模的值 2631的超^n级弱化版.写2631之前能够拿这个练练手 ...

  10. poj 2828 Buy Tickets 【买票插队找位置 输出最后的位置序列+线段树】

    题目地址:http://poj.org/problem?id=2828 Sample Input 4 0 77 1 51 1 33 2 69 4 0 20523 1 19243 1 3890 0 31 ...

随机推荐

  1. matlab 直方图均衡化(含rgb)

    步骤: 统计原图像素每个像素的个数 统计原图像<每个灰度级的像素的累积个数 家里灰度级得映射规则 将原图每个像素点的灰度映射到新图 代码: clear all I=imread('1.jpg') ...

  2. Windows资源监控工具大全

    在利用LoadRunner进行性能测试的时候,Windows服务器的资源是经常需要监控的对象.其实除了LoadRunner提供的计数器,似乎Window服务器并不像Unix或者Linux提供众多的性能 ...

  3. LoadRunner数据库监控指标

    SQL Server 注:以下指标取自SQL Server自身提供的性能计数器. 指标名称 指标描述 指标范围 指标单位 1.SQL Server中访问方法(Access Methods)对象包含的性 ...

  4. mysql学习之主从复制

    该文使用mysql5.5 centos6.5 64位 一.主从复制的作用 1.如果主服务器出现问题,可以快速切换到从服务器. 2.对与实时性要求不高或者更新不频繁的应用可以在从服务器上执行查询操作,降 ...

  5. [Leetcode] 3.Longest Substring Without Repeating Characters(unordered_map)

    通过把未访问的结点放到unordered_map中来判断是否重复,代码如下: class Solution { public: int lengthOfLongestSubstring(string ...

  6. 【转】自编码算法与稀疏性(AutoEncoder and Sparsity)

    目前为止,我们已经讨论了神经网络在有监督学习中的应用.在有监督学习中,训练样本时有类别标签的.现在假设我们只有一个没带类别标签的训练样本集合  ,其中  .自编码神经网络是一种无监督学习算法,它使用了 ...

  7. P2580 于是他错误的点名开始了

    题目背景 XS中学化学竞赛组教练是一个酷爱炉石的人. 他会一边搓炉石一边点名以至于有一天他连续点到了某个同学两次,然后正好被路过的校长发现了然后就是一顿欧拉欧拉欧拉(详情请见已结束比赛CON900). ...

  8. 具体数学二项式至生成函数章-----致敬Kunth

    关于标题取得这么奇怪.因为在具体数学中.这两章是分开叙述的.并且分别叙述得淋漓尽致! 我只参悟其中关于生成函数的一小部分内容(暂时于我够用了.) 提二项式系数之前不得不提组合数.以往在高中用的是符号C ...

  9. 【刷题】BZOJ 1003 [ZJOI2006]物流运输

    Description 物流公司要把一批货物从码头A运到码头B.由于货物量比较大,需要n天才能运完.货物运输过程中一般要转停好几个码头.物流公司通常会设计一条固定的运输路线,以便对整个运输过程实施严格 ...

  10. [洛谷P4721]【模板】分治 FFT_求逆

    题目大意:给定长度为$n-1$的数组$g_{[1,n)}$,求$f_{[0,n)}$,要求: $$f_i=\sum_{j=1}^if_{i-j}g_j\\f_0=1$$ 题解:分治$FFT$博客,发现 ...