前 言:

一直很想写这道括号树。。毕竟是在去年折磨了我4个小时的题。。。。

上午小测3 T1 括号序列

前言:

原来这题是个dp啊。。。这几天出了好几道dp,我都没看出来,我竟然折磨菜。

考试的时候先打了个暴力,然后就开始往容斥上想。。。。

解析:

考虑dp。

令dp[i] 表示以i为结尾的,合法的子串数量。

令match[i] 表示进行括号匹配时,与i匹配的括号的编号。

(以上i都是右括号,如果是左括号置为0即可)

然后,就有: if(match[i]) dp[i]=dp[match[i]-1]+1;

这个转移方程的含义如下:

首先是前面的判断语句。必须是在i有匹配的情况下。

这样就排除了两种不可能的情况,一种是i是左括号,另一种是i是右括号,但在进行括号匹配时,没有与其匹配的左括号。

显然以上两种情况,i都不可能成为一个合法字串的结尾。

然后是要先给dp[i]加上1。这是以match[i]为起点,i为终点的子串的贡献。

其次要加上dp[match[i]-1];

这时分两种情况讨论。

第一种是 s[match[i]-1]==')' : 好丑的图

此时以i为结尾的子串还可能继续向左延伸,只要加上dp[match[i]-1]即可。

另外一种是 s[match[i]-1]=='(':

此时不能继续向左延伸,所以不加,但是因为dp[match[i]-1]是0,所以加上也不会错(主要是这样写起来方便)

说的有些麻烦了,其实还是挺显然的。

代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1000000+10;
#define gc() (p1 == p2 ? (p2 = buf + fread(p1 = buf, 1, 1 << 20, stdin), p1 == p2 ? EOF : *p1++) : *p1++)
#define read() ({ register int x = 0, f = 1; register char c = gc(); while(c < '0' || c > '9') { if (c == '-') f = -1; c = gc();} while(c >= '0' && c <= '9') x = x * 10 + (c & 15), c = gc(); f * x; })
char buf[1 << 20], *p1, *p2;
char s[maxn];
int n,top;
int dp[maxn];
int match[maxn];
ll ans;
struct node{
int pos;
char c;
node(){}
node(int x,char y){
pos=x;
c=y;
}
}Stack[maxn];
void Solve(){
scanf("%s",s+1);
n=strlen(s+1);
Stack[++top]=node(1,s[1]);
for(int i=2;i<=n;++i){
if(s[i]==')'&&Stack[top].c=='('){
node t=Stack[top];
top--;
match[i]=t.pos;
}else Stack[++top]=node(i,s[i]);
}
for(int i=1;i<=n;++i){
if(match[i]){
dp[i]=1+dp[match[i]-1];
}
}
for(int i=1;i<=n;++i) ans+=dp[i];
printf("%lld\n",ans);
}
int main(){
freopen("bracket.in","r",stdin);
freopen("bracket.out","w",stdout);
Solve();
return 0;
}

luogu P5658 [CSP/S 2019 D1T2] 括号树

前言:

其实应该不是很难吧。。。

解析:

和上一道题类似,但不是完全相同废话

所以一定要看清题啊。。。

这次问的是每个字符串的合法子串数量。。。我当成以每个字符结尾的合法字串数量了,直接暴毙。。。

会上面那道题,这个就简单多了。

先令dp[i]表示以i结尾的合法字子串数量,然后求个树上前缀和就行了。

照上个题的思路,改改式子:

if(match[i]) dp[i]=dp[fa[match[i]]]+1

最后。。。

不开long long见祖宗!

代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=500000+10;
#define gc() (p1 == p2 ? (p2 = buf + fread(p1 = buf, 1, 1 << 20, stdin), p1 == p2 ? EOF : *p1++) : *p1++)
#define read() ({ register int x = 0, f = 1; register char c = gc(); while(c < '0' || c > '9') { if (c == '-') f = -1; c = gc();} while(c >= '0' && c <= '9') x = x * 10 + (c & 15), c = gc(); f * x; })
char buf[1 << 20], *p1, *p2;
struct node{
int to,nxt;
}edge[maxn<<1];
int head[maxn],fa[maxn],match[maxn];
ll dp[maxn];
char s[maxn];
struct Node{
int pos;
char c;
Node(){}
Node(int x,char y){
pos=x;
c=y;
}
}Stack[maxn];
int n,cnt,top;
ll ans;
void add(int from,int to){
edge[++cnt].to=to;
edge[cnt].nxt=head[from];
head[from]=cnt;
}
void dfs1(int u){
Node t=Stack[top];
if(t.c=='('&&s[u]==')'){
match[u]=t.pos;
top--;
for(int i=head[u];i;i=edge[i].nxt){
int v=edge[i].to;
if(v==fa[u]) continue;
dfs1(v);
}
Stack[++top]=Node(t.pos,t.c);
}else{
Stack[++top]=Node(u,s[u]);
for(int i=head[u];i;i=edge[i].nxt){
int v=edge[i].to;
if(v==fa[u]) continue;
dfs1(v);
}
top--;
}
}
void dfs2(int u){
if(match[u]) dp[u]=dp[fa[match[u]]]+1;
for(int i=head[u];i;i=edge[i].nxt){
int v=edge[i].to;
if(v==fa[u]) continue;
dfs2(v);
}
}
void dfs3(int u,int f){
dp[u]+=dp[f];
for(int i=head[u];i;i=edge[i].nxt){
int v=edge[i].to;
if(v==fa[u]) continue;
dfs3(v,u);
}
}
void Solve(){
scanf("%d%s",&n,s+1);
for(int i=2;i<=n;++i){
scanf("%d",&fa[i]);
add(i,fa[i]);
add(fa[i],i);
}
dfs1(1);
dfs2(1);
dfs3(1,0);
for(int i=1;i<=n;++i) ans^=(1ll*i*dp[i]);
printf("%lld\n",ans);
}
int main(){
// freopen("brackets.in","r",stdin);
// freopen("brackets.out","w",stdout);
Solve();
return 0;
}

上午小测3 T1 括号序列 && luogu P5658 [CSP/S 2019 D1T2] 括号树 题解的更多相关文章

  1. 上午小测1 T1 木板 题解

    前言: WTCL,居然折磨煎蛋的性质都忘记了,WTCL. 考场上想出来了正解,就差一点就能A掉,挺难受的. 要记住一个数n可能会有一个大于\(\sqrt{n}\)的质因子..我忘记把它加进去了.... ...

  2. CSP-S 2019 D1T2 括号树

    题目链接:[https://www.luogu.com.cn/problem/P5658] 思路: 这道题不难.(为什么我在考场上一点思路也没有??) 假设我们已经处理到树上的节点u(假设1为根节点) ...

  3. 上午小测1 B.序列 哈希表+数学

    题目描述 \(EZ\) 每周一都要举行升旗仪式,国旗班会站成一整列整齐地向前行进. 郭神摄像师想要选取其中一段照下来.他想让这一段中每个人的身高成等比数列,展示出最萌身高差.但他发现这个太难办到了.于 ...

  4. 括号序列模型--序列dp--U86873 小Y的精灵国机房之旅

    括号序列模型及解法 >Codeforces314E◦给定一个长度为n的仅包含左右括号和问号的字符串,将问号变成左括号或右括号使得该括号序列合法,求方案总数.◦例如(())与()()都是合法的括号 ...

  5. 学长小清新题表之UOJ 31.猪猪侠再战括号序列

    学长小清新题表之UOJ 31.猪猪侠再战括号序列 题目描述 大家好我是来自百度贴吧的_叫我猪猪侠,英文名叫\(\_CallMeGGBond\). 我不曾上过大学,但这不影响我对离散数学.复杂性分析等领 ...

  6. 2017-5-14 湘潭市赛 Parentheses 转化思想+贪心 使括号序列合法的最小花费。满足前面左括号的数量>=有括号的数量。

    Parentheses Accepted : Submit : Time Limit : MS Memory Limit : KB Parentheses Bobo has a very long s ...

  7. 括号序列(区间dp)

    括号序列(区间dp) 输入一个长度不超过100的,由"(",")","[",")"组成的序列,请添加尽量少的括号,得到一 ...

  8. 括号序列(Poj1141)

    Poj1141 题目描述: 定义合法的括号序列如下: 1 空序列是一个合法的序列 2 如果S是合法的序列,则(S)和[S]也是合法的序列 3 如果A和B是合法的序列,则AB也是合法的序列 例如:下面的 ...

  9. 括号序列的dp问题模型

    括号序列的dp问题模型 Codeforces314E ◦给定一个长度为n的仅包含左括号和问号的字符串,将问号变成左括号或 右括号使得该括号序列合法,求方案总数. ◦例如(())与()()都是合法的括号 ...

随机推荐

  1. element后端管理布局

    <template> <el-container> <el-header> <Header></Header> <span class ...

  2. word文档转成图片

    1:先把word文档转成pdf格式  这个是在word中转成pdf格式,保存好 2:再把pdf格式转成图片 在这个链接中打开https://smallpdf.com/cn/pdf-converter, ...

  3. 通过Kubernetes监控探索应用架构,发现预期外的流量

    大家好,我是阿里云云原生应用平台的炎寻,很高兴能和大家一起在 Kubernetes 监控系列公开课上进行交流.本次公开课期望能够给大家在 Kubernetes 容器化环境中快速发现和定位问题带来新的解 ...

  4. Spring Boot中有多个@Async异步任务时,记得做好线程池的隔离!

    通过上一篇:配置@Async异步任务的线程池的介绍,你应该已经了解到异步任务的执行背后有一个线程池来管理执行任务.为了控制异步任务的并发不影响到应用的正常运作,我们必须要对线程池做好相应的配置,防止资 ...

  5. 安卓开发 利用百度识图api进行物体识别

    前文 之前的随笔中,已经通过相机或相册获取到了我们想要的图片,接下来进行识图api的配置工作.我使用的是百度的api,利用python获取信息,并在MainActivity中进行调用来输出信息. 一. ...

  6. java线程day-01

    综述:下面写的是我学习java线程时做的一些笔记和查阅的一些资料总结而成.大多以问答的形式出现. 一.什么是线程? 答:线程是一个轻量级的进程,现在操作系统中一个基本的调度单位,而且线程是彼此独立执行 ...

  7. git实战-linux定时监控github更新状态(二)

    系列文章 git介绍-常用操作(一)✓ git实战-linux定时监控github更新状态(二)✓ 本文主要内容 如何查看github的本地仓库和远程仓库的同步情况 linux服务器定时监控githu ...

  8. centos虚拟机中挂新硬盘

    配置一台centos7,主硬盘20G装系统:副硬盘20G作为数据盘(格式:XFS)挂载到根目录:/vdir/ ,XFS是高性能文件系统. 外层vm硬盘添加好后,执行下面 1.fdisk -l //查看 ...

  9. 入坑Java的自学之路

    # 入坑Java的自学之路 ## 基础知识 - 编程语言:Java python c- 基本算法- 基本网络知识 tcp/ip http/https- 基本的设计模式 ------ ## 工具方面 - ...

  10. [转载]php连接postgreSQL数据库及其操作(php5,postgreSQL9)

    数据库连接:dbconn.php<?php$conn = pg_connect("host=localhost port=5432 dbname=myd user=postgres p ...