首页 > 其他分享 >P8997 题解

P8997 题解

时间:2024-08-13 20:07:01浏览次数:5  
标签:叶子 num0 num1 题解 运算符 ans P8997 dp

P8997

思路

按题意模拟,用栈建出二叉树,叶子节点是要填的值,非叶子是运算符。

判断一个叶子能贡献能填哪些数并最终成为答案,即 dp 计算要使该叶子的值 \(ans\) 成为答案最少要填 \(num0\) 个 \(<=ans\) 和 \(num1\) 个 \(>ans\) 的数。发现 dp 只与 \(\le ans\) 和 \(>ans\) 的数的个数有关,可以统一计算。

设 \(dp_{u,0/1,0/1}\) 表示 \(u\) 子树内,\(u\) 处的值 \(\le ans\) 或 \(>ans\),\(num0\) 或 \(num1\) 最少为多少。根据 \(u\) 处的运算符分类讨论转移。如果 \(u\) 处运算符为 \(<\),如果 \(u\) 的值 \(\le ans\),那 \(ls\) 和 \(rs\) 的值有一个 \(\le ans\) 即可;否则两个都有 \(>ans\)。运算符为 \(>\) 同理。

对于每个叶子算限制,只与从根到 \(u\) 的 dp 值有关。因为叶子的值为 \(ans\),所以在路径上如果 \(u\) 点运算符为 \(<\),要进入左儿子,那么右儿子的值 \(>ans\),左儿子的值 \(\le ans\),\(num0\) 加上 \(dp_{rs,1,0}\),\(num1\) 加上 \(dp_{rs,1,1}\)。其他同理。

可以发现放在一个叶子的答案是一个区间 \([num0+1,n-num1]\),差分维护区间加,最后计算大于 \(0\) 的位置数。

code

int n,m,ans;
char s[maxn<<2];
int st[maxn],tp;
int ls[maxn],rs[maxn],op[maxn],dp[maxn][2][2],idx;
void dfs(int u){
	if(op[u]==3){
		dp[u][0][0]=1,dp[u][1][1]=1;
		return ;
	}
	dfs(ls[u]),dfs(rs[u]);
	if(op[u]==1){
		dp[u][0][0]=min({dp[ls[u]][0][0]+dp[rs[u]][0][0],dp[ls[u]][0][0]+dp[rs[u]][1][0],dp[ls[u]][1][0]+dp[rs[u]][0][0]});
		dp[u][0][1]=min({dp[ls[u]][0][1]+dp[rs[u]][0][1],dp[ls[u]][0][1]+dp[rs[u]][1][1],dp[ls[u]][1][1]+dp[rs[u]][0][1]});
		dp[u][1][0]=dp[ls[u]][1][0]+dp[rs[u]][1][0];
		dp[u][1][1]=dp[ls[u]][1][1]+dp[rs[u]][1][1];
	}
	else{
		dp[u][0][0]=dp[ls[u]][0][0]+dp[rs[u]][0][0];
		dp[u][0][1]=dp[ls[u]][0][1]+dp[rs[u]][0][1];
		dp[u][1][0]=min({dp[ls[u]][1][0]+dp[rs[u]][1][0],dp[ls[u]][1][0]+dp[rs[u]][0][0],dp[ls[u]][0][0]+dp[rs[u]][1][0]});
		dp[u][1][1]=min({dp[ls[u]][1][1]+dp[rs[u]][1][1],dp[ls[u]][1][1]+dp[rs[u]][0][1],dp[ls[u]][0][1]+dp[rs[u]][1][1]});
	}
}
int f[maxn];
void calc(int u,int l,int r){
	if(op[u]==3){
		f[l+1]++,f[m-r+1]--;
		return ;
	}
	if(op[u]==1){
		calc(ls[u],l+dp[rs[u]][1][0],r+dp[rs[u]][1][1]),calc(rs[u],l+dp[ls[u]][1][0],r+dp[ls[u]][1][1]);
	}
	else{
		calc(ls[u],l+dp[rs[u]][0][0],r+dp[rs[u]][0][1]),calc(rs[u],l+dp[ls[u]][0][0],r+dp[ls[u]][0][1]);
	}
}
void work(){
	scanf("%s",s+1);n=strlen(s+1);
	for(int i=1;i<=n;i++){
		if(s[i]=='m'){
			if(s[i+1]=='i')st[++tp]=++idx,op[idx]=1;
			else st[++tp]=++idx,op[idx]=2;
			if(s[i-1]=='(')ls[st[tp-1]]=st[tp];
			if(s[i-1]==',')rs[st[tp-1]]=st[tp];
		}
		if(s[i]=='?'){
			op[++idx]=3;++m;
			if(s[i-1]=='(')ls[st[tp]]=idx;
			if(s[i-1]==',')rs[st[tp]]=idx;			
		}
		if(s[i]==')')tp--;
	}
	dfs(1);calc(1,0,0);
	for(int i=1;i<=m;i++)f[i]+=f[i-1],ans+=f[i]>0;
	printf("%lld\n",ans);
}

标签:叶子,num0,num1,题解,运算符,ans,P8997,dp
From: https://www.cnblogs.com/yhddd/p/18357606

相关文章

  • P8996 题解
    P8996思路当有\(a_i<a_j\)时,先放\(a_i\),再放\(i\)之后连续的\(a_k<a_i\)。设\(i\)后第一个比\(a_i\)大的位置是\(nxt_i\),对于一个前缀最大值位置\(i\),合并后\([i,nxt_i)\)的顺序不变且依然连续。让前缀最大值\(a_l\)代表整个区间,可以看做合并是将两个序列的前缀......
  • arc182c 题解
    arc182c思路有\(6\)个小于\(14\)的质数,设这\(6\)个质数的指数分别为\(x_1,\dotsb,x_6\)。\(ans=\sum(\prod_{i=1}^d(x_i+1))\)。状压这\(6\)个数,维护\(val_s=\prod_{i=1}^6(x_i\times[s二进制第i位为1]+[s二进制第i位为0])\)。当加入一个数时,某些\(x_i\)会加......
  • CF1294F 题解
    Part.0闲话更好的观看体验目前题解区里大多数巨佬都是采用的树形dp和暴力等方法,看见没有我这种做法,欢迎指出做法问题或hack代码。Part.1题意给定一棵树,选\(3\)个点\(a,b,c\),求\(a\)到\(b\)的路径与\(a\)到\(c\)的路径与\(b\)到\(c\)的路径上一共有多少......
  • 新坑:信息学奥赛一本通题解(3001~3005)
    前言Hello,大家好我是文宇,开个新坑,是关于信息学奥赛一本通的坑,就是信奥赛题解.(这里指编程启蒙的题库)因为作者的洛谷还在写,只是信奥赛的题写的比较多,所以先做信奥赛的.信奥赛的网址是信息学奥赛一本通-编程启蒙(C++版)在线评测系统(挖坑:作者以后可能还会有信奥赛本体......
  • 生活在hzoi上 题解
    生活在hzoi上题解考虑有两棵树怎么做,显然是\(y^{n-k}=y^{n-\left\vertE_1\capE_2\right\vert}\)其中\(E_1\)和\(E_2\)是两棵树的边集发现上边那个\(k\)是两棵树边集交构成的图的连通块个数\(\left\vertE_1\capE_2\right\vert\)就是两棵树交的连通块数量......
  • 记一次NoClassDeffoundEror问题解决过程
    背景:在对某台计算服务器进行代码修改后,发现es查询报错,抛出异常如下: 思路: 1.jar包冲突   查询了对应jar的pom文件,发现只有一个es的版本jar包,不存在冲突,百思不得其解。2.本地环境问题   清理idea的缓存,发行问题仍然存在最后翻阅资料,打了断点追踪异常抛出的地方,......
  • ARC182 题解
    A-ChmaxRush!发现一个数能向哪边覆盖只由再他之后操作且\(v\)比他大的操作决定。所以扫一遍确定方向之后乘起来就好。B-|{floor(A_i/2^k)}|首先不难发现\(<2_{k-1}\)的元素是无用的,因为它们会由\(\ge2^{k-1}\)的元素除以2的幂得到。先想上界。对于\(0\l......
  • ARC182B |{floor(A_i/2^k)}| 题解
    ARC182B|{floor(A_i/2^k)}|题解题目大意定义一个长度为\(N\)的序列\(A\)的分数为能被表示成\(\lfloor{A_i\over2^k}\rfloor\)的数的个数,其中\(i=1,2,\dots,N\),\(k\)为任意自然数。给定\(N,K\),求长度为\(N\)且元素大小都在\(2^K-1\)内的所有序列的分数的最大值......
  • 【题解】 [USACO 2007 FEB] Cow Party S
    题目描述题目大意给定一个有向图,以及一个顶点。求其他所有点到给定点,再从给定点回到各自起始点的最短路中的最大值。思路本题主要考查:对单源最短路算法的熟练运用。最短路总共分为2段:其他所有点到给定点、给定点回到各自起始点。首先求第一段:可以在原图的基础上建一个反向图......
  • 洛谷 P4305 不重复数字——题解
    洛谷P4305题解传送锚点摸鱼环节[JLOI2011]不重复数字题目描述给定\(n\)个数,要求把其中重复的去掉,只保留第一次出现的数。输入格式本题有多组数据。第一行一个整数\(T\),表示数据组数。对于每组数据:第一行一个整数\(n\)。第二行\(n\)个数,表示给定的数。输出格......