题意:给定一个只含'(',')'的括号序列,有m个操作,改变某个位置的括号或者询问区间[L,R]内的括号进行配对后剩下的第K个括号的位置(配对的括号从原序列中删掉)。

思路:首先对于一个括号序列,进行配对后剩下的括号序列必定是")))...)((...(("这种形式的,令(x,y)表示当前区间的剩下的右括号数为x,左括号数为y这个状态,不难发现它可以通过子区间来合并,因此考虑用线段树解决。对于单点更新比较容易,直接在叶子节点改变一下,然后向上更新即可,对于L,R,K这个询问,首先进行一次区间[L,R]的查找,得到最终的左括号和右括号数目,如果数目和小于K,则答案为-1,否则可以确定第K个括号的是哪种类型的括号,假设第K个括号是右括号,则问题转化为求第K个右括号的位置,在线段树上二分即可,二分的时候需要注意,假定答案在右区间,且左区间有x个右括号y个左括号,则在右区间应查找第K-x+y个右括号。

 #pragma comment(linker, "/STACK:102400000,102400000")

 #include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstdlib>
#include <cstring>
#include <map>
#include <queue>
#include <deque>
#include <cmath>
#include <ctime>
#include <cctype>
#include <set>
#include <bitset>
#include <functional>
#include <numeric>
#include <stdexcept>
#include <utility>
#include <vector> using namespace std; #define mem0(a) memset(a, 0, sizeof(a))
#define mem_1(a) memset(a, -1, sizeof(a))
#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1 | 1
#define define_m int m = (l + r) >> 1
#define rep_up0(a, b) for (int a = 0; a < (b); a++)
#define rep_up1(a, b) for (int a = 1; a <= (b); a++)
#define rep_down0(a, b) for (int a = b - 1; a >= 0; a--)
#define rep_down1(a, b) for (int a = b; a > 0; a--)
#define all(a) (a).begin(), (a).end()
#define lowbit(x) ((x) & (-(x)))
#define constructInt4(name, a, b, c, d) name(int a = 0, int b = 0, int c = 0, int d = 0): a(a), b(b), c(c), d(d) {}
#define constructInt3(name, a, b, c) name(int a = 0, int b = 0, int c = 0): a(a), b(b), c(c) {}
#define constructInt2(name, a, b) name(int a = 0, int b = 0): a(a), b(b) {}
#define pchr(a) putchar(a)
#define pstr(a) printf("%s", a)
#define sstr(a) scanf("%s", a)
#define sint(a) scanf("%d", &a)
#define sint2(a, b) scanf("%d%d", &a, &b)
#define sint3(a, b, c) scanf("%d%d%d", &a, &b, &c)
#define pint(a) printf("%d\n", a)
#define test_print1(a) cout << "var1 = " << a << endl
#define test_print2(a, b) cout << "var1 = " << a << ", var2 = " << b << endl
#define test_print3(a, b, c) cout << "var1 = " << a << ", var2 = " << b << ", var3 = " << c << endl typedef long long LL;
typedef pair<int, int> pii;
typedef vector<int> vi; const int dx[] = {, , -, , , , -, -};
const int dy[] = {-, , , , , -, , - };
const int maxn = 2e5 + ;
const int md = ;
const int inf = 1e9 + ;
const LL inf_L = 1e18 + ;
const double pi = acos(-1.0);
const double eps = 1e-; template<class T>T gcd(T a, T b){return b==?a:gcd(b,a%b);}
template<class T>bool max_update(T &a,const T &b){if(b>a){a = b; return true;}return false;}
template<class T>bool min_update(T &a,const T &b){if(b<a){a = b; return true;}return false;}
template<class T>T condition(bool f, T a, T b){return f?a:b;}
template<class T>void copy_arr(T a[], T b[], int n){rep_up0(i,n)a[i]=b[i];}
int make_id(int x, int y, int n) { return x * n + y; } int ans;
char s[maxn]; struct SegTree {
struct Node {
int cl, cr;
} tree[maxn << ]; Node merge(Node b, Node c) {
Node a;
a.cl = c.cl;
a.cr = b.cr;
if (b.cl <= c.cr) a.cr += c.cr - b.cl;
else a.cl += b.cl - c.cr;
return a;
} void build(int l, int r, int rt) {
if (l == r) {
char ch = s[l - ];
tree[rt].cl = ch == '(';
tree[rt].cr = ch == ')';
return ;
}
define_m;
build(lson);
build(rson);
tree[rt] = merge(tree[rt << ], tree[rt << | ]);
} void update(int u, int l, int r, int rt) {
if (l == r) {
swap(tree[rt].cl, tree[rt].cr);
return ;
}
define_m;
if (u <= m) update(u, lson);
else update(u, rson);
tree[rt] = merge(tree[rt << ], tree[rt << | ]);
} Node query(int L, int R, int l, int r, int rt) {
if (L <= l && r <= R) return tree[rt];
define_m;
if (R <= m) return query(L, R, lson);
if (L > m) return query(L, R, rson);
return merge(query(L, R, lson), query(L, R, rson));
} Node find1(int L, int R, int k, int l, int r, int rt) {
if (L <= l && r <= R && (k > tree[rt].cr || k <= || ans)) return tree[rt];
if (l == r) {
ans = l;
return tree[rt];
}
define_m;
if (R <= m) return find1(L, R, k, lson);
if (L > m) return find1(L, R, k, rson);
Node buf = find1(L, R, k, lson);
if (ans) return buf;
return merge(buf, find1(L, R, k - buf.cr + buf.cl, rson));
} Node find2(int L, int R, int k, int l, int r, int rt) {
if (L <= l && r <= R && (k > tree[rt].cl || k <= || ans)) return tree[rt];
if (l == r) {
ans = l;
return tree[rt];
}
define_m;
if (R <= m) return find2(L, R, k, lson);
if (L > m) return find2(L, R, k, rson);
Node buf = find2(L, R, k, rson);
if (ans) return buf;
return merge(find2(L, R, k - buf.cl + buf.cr, lson), buf);
}
};
SegTree ST;
int main() {
//freopen("in.txt", "r", stdin);
int T, n, m;
cin >> T;
while (T --) {
cin >> n >> m;
scanf("%s", s);
ST.build(, n, );
rep_up0(i, m) {
int id;
sint(id);
if (id == ) {
int u;
sint(u);
ST.update(u, , n, );
}
else {
int u, v, k;
sint3(u, v, k);
SegTree::Node buf = ST.query(u, v, , n, );
if (buf.cl + buf.cr < k) {
puts("-1");
continue;
}
ans = ;
if (buf.cr >= k) ST.find1(u, v, k, , n, );
else ST.find2(u, v, buf.cl + buf.cr - k + , , n, );
printf("%d\n", ans);
}
}
}
return ;
}

[hdu5217]线段树的更多相关文章

  1. bzoj3932--可持久化线段树

    题目大意: 最近实验室正在为其管理的超级计算机编制一套任务管理系统,而你被安排完成其中的查询部分.超级计算机中的 任务用三元组(Si,Ei,Pi)描述,(Si,Ei,Pi)表示任务从第Si秒开始,在第 ...

  2. codevs 1082 线段树练习 3(区间维护)

    codevs 1082 线段树练习 3  时间限制: 3 s  空间限制: 128000 KB  题目等级 : 大师 Master 题目描述 Description 给你N个数,有两种操作: 1:给区 ...

  3. codevs 1576 最长上升子序列的线段树优化

    题目:codevs 1576 最长严格上升子序列 链接:http://codevs.cn/problem/1576/ 优化的地方是 1到i-1 中最大的 f[j]值,并且A[j]<A[i] .根 ...

  4. codevs 1080 线段树点修改

    先来介绍一下线段树. 线段树是一个把线段,或者说一个区间储存在二叉树中.如图所示的就是一棵线段树,它维护一个区间的和. 蓝色数字的是线段树的节点在数组中的位置,它表示的区间已经在图上标出,它的值就是这 ...

  5. codevs 1082 线段树区间求和

    codevs 1082 线段树练习3 链接:http://codevs.cn/problem/1082/ sumv是维护求和的线段树,addv是标记这歌节点所在区间还需要加上的值. 我的线段树写法在运 ...

  6. PYOJ 44. 【HNSDFZ2016 #6】可持久化线段树

    #44. [HNSDFZ2016 #6]可持久化线段树 统计 描述 提交 自定义测试 题目描述 现有一序列 AA.您需要写一棵可持久化线段树,以实现如下操作: A v p x:对于版本v的序列,给 A ...

  7. CF719E(线段树+矩阵快速幂)

    题意:给你一个数列a,a[i]表示斐波那契数列的下标为a[i],求区间对应斐波那契数列数字的和,还要求能够维护对区间内所有下标加d的操作 分析:线段树 线段树的每个节点表示(f[i],f[i-1])这 ...

  8. 【BZOJ-3779】重组病毒 LinkCutTree + 线段树 + DFS序

    3779: 重组病毒 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 224  Solved: 95[Submit][Status][Discuss] ...

  9. 【BZOJ-3673&3674】可持久化并查集 可持久化线段树 + 并查集

    3673: 可持久化并查集 by zky Time Limit: 5 Sec  Memory Limit: 128 MBSubmit: 1878  Solved: 846[Submit][Status ...

随机推荐

  1. 编码理解的漫漫长路(Unicode、GBK、ISO)

    Ø 那么现在开始康康都有哪些编码方式  1.  ASCII

  2. python之pymysql库连接mysql实现增、删、改、查

    安装第三方库pymysql 命令行cmd下通过pip install pymysql进行安装,安装完成后自行pip list可查看对应的版本信息 建立连接 1 #导入pymysql库 2 import ...

  3. Linux-LAMP虚拟主机配置

    1.配置用户认证 <Directory /data/discuz/passwd> AllowOverride AuthConfig AuthName "自定义的" Au ...

  4. SpringCloud-Config 配置中心

    概述 分布式系统面临的问题 微服务意味着要将单体应用中的业务拆分成一个个的子服务,这些服务都需要必要的配置信息才能运行,如果有上百个微服务,上百个配置文件,管理起来是非常困难的,这时候,一套集中式的. ...

  5. Flutter 分页功能表格控件

    老孟导读:前2天有读者问到是否有带分页功能的表格控件,今天分页功能的表格控件详细解析来来. PaginatedDataTable PaginatedDataTable是一个带分页功能的DataTabl ...

  6. 10w+QPS 的 Redis 真的只是因为单线程和内存?360&#176; 深入底层设计为你揭开 Redis 神秘面纱!

    原文链接:10w+QPS 的 Redis 真的只是因为单线程和内存?360° 深入底层设计为你揭开 Redis 神秘面纱! 你以为 Redis 这么快仅仅因为单线程和基于内存? 那么你想得太少了,我个 ...

  7. JAVA企业级应用TOMCAT实战(二)

    使用普通用户运行 使用普通用户来部署服务是比较安全的做法 [root@tomcat application]# useradd -u tomcat [root@tomcat application]# ...

  8. 深拷贝、浅拷贝与Cloneable接口

    深拷贝与浅拷贝 浅拷贝 public class Student implements Cloneable{ Integer a; Integer b; @Override protected Obj ...

  9. 源码安装nginx 方法二

    yum 仓库不能用大写字母 [root@oldboy conf.d]# gzip * 压缩当前目录下的所有文件 gzip ./* gzip . gzip./ # 关闭防火墙和selinux [root ...

  10. 本周ASP.NET英文技术文章推荐[02/03 - 02/16]:MVC、Visual Studio 2008、安全性、性能、LINQ to JavaScript、jQuery...

    摘要 继续坚持,继续推荐.本期共有9篇文章: 最新的ASP.NET MVC框架开发计划 Visual Studio 2008 Web开发相关的Hotfix发布 ASP.NET安全性教程系列 ASP.N ...