首页 > 其他分享 >Luogu1310 表达式的值 - 模拟 -

Luogu1310 表达式的值 - 模拟 -

时间:2022-08-27 19:46:49浏览次数:78  
标签:Luogu1310 ++ res 表达式 curans int 模拟 curfig mod

题目链接:https://www.luogu.com.cn/problem/P1310

题解:
先考虑没有括号的情况,显然可以根据 + 的位置划分成若干段,每段的结果必须为0
如何处理?因为每段+之间必然均为,答案就是\(2^{f}-1\),f为该段所能插入的数的个数,累乘即可
现在考虑有括号的情况。基本思路不变,考虑递归实现该过程
维护两个值\(a,b\),其中\(a\)代表该段(两个+之间)能填的数的个数,\(b\)表示该段最终结果得到0的方案数
还是考虑两个+之间的段。考虑最终结果为1的答案,最后容斥一下即可(注意考虑1是因为只有11=1方便计数)
由于1
1=1,两个相邻*之间必然填1,对于括号,递归实现之后求出\(a,b\),该段结果为1的方案数即为\(2^a-b\)
最后容斥一下即可得到结果为0的方案数
实现时有一些细节要注意,比如数字个数的判断

// by Balloons
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define mpr make_pair
#define debug() cerr<<"Madoka"<<endl
#define rep(i,a,b) for(int (i)=(a);(i)<=(b);(i)++)

using namespace std;

typedef long long LL;

const int inf = 1e9, INF = 0x3f3f3f3f,maxn=2e5+5,mod=10007;

int n;
char s[maxn];

int pw(int x){
	if(!x)return 1;if(x==1)return 2;
	int mid = pw(x>>1);
	if(x&1)return 2ll*mid*mid%mod;
	return 1ll*mid*mid%mod;
}
int nxt[maxn];
int stk[maxn], tp=0;

pair<int,int> dfs(int l,int r){
	int curfig = 0, curans = 1, ans=1, totfig=0;
	for(int i=l;i<=r;){
		if(s[i] == '('){
			pair<int,int> res = dfs(i+1, nxt[i]-1);
			curfig += res.first;
			totfig += res.first;
			curans = 1ll*curans * ((pw(res.first) - res.second%mod + mod)%mod) % mod;
			i = nxt[i]+1;
			continue;
		}
		if(s[i] == '*'){
			if((i > l && s[i-1] != ')') || (i == l)){
				++ curfig;
				++ totfig;
			}
		}
		if(s[i] == '+'){
			if((i>l && (s[i-1] != ')')) || (i == l))++ curfig,++ totfig;
			ans = 1ll*ans*((pw(curfig) - curans+mod) % mod)%mod;
			curfig = 0;
			curans = 1;
		}
		i ++;
	}
	if(s[r] != ')')++ curfig, ++ totfig;
	ans = 1ll*ans*((pw(curfig) - curans+mod)%mod)%mod;
	return mpr(totfig, ans);
}

signed main(){
	scanf("%d",&n);
	scanf("%s",s + 1);
	for(int i=1;i<=n;i++){
		if(s[i] == '(')stk[++ tp] = i;
		if(s[i] == ')'){
			int cur = stk[tp --];
			nxt[cur] =i;
		}
	}
	pair<int,int>res = dfs(1,n);
	printf("%d\n",res.second);

	return 0;
}


标签:Luogu1310,++,res,表达式,curans,int,模拟,curfig,mod
From: https://www.cnblogs.com/SkyRainWind/p/16631299.html

相关文章

  • 计算四则表达式值 Golang
    思路:先转逆波兰,再求值packagemainimport( "fmt" "strconv" "strings")funcmid2fix(sstring)[]string{ res:=[]string{} exp:=strings.Fields(s) ss......
  • Lambda表达式
    作用简化匿名内部类的代码写法格式(匿名内部类被重写方法的形参列表)->{被重写方法的方法体代码}注意:Lambda表达式只能简化函数式接口的匿名内部类的写法形式......
  • C#验证邮箱格式正则表达式
    1///<summary>2///验证邮箱格式3///</summary>4///<paramname="email"></param>5///<returns></returns>6......
  • Android Studio原生模拟器崩溃
    当你用AndroidStudio原生模拟器测试某个程序的时候模拟器突然就崩溃了如下图所示 当我们再次启动模拟器的时候提示我们已经有一个模拟器在启动中但是我们并没有看到呀......
  • LeetCode 150. 逆波兰表达式求值
    思路:当字符串为运算符号是弹出栈中两个数字进行运算stoi("1")将string转换为intclassSolution{public:intevalRPN(vector<string>&tokens){stack<......
  • 打了一场模拟赛的心态,总结
       今天打了一场模拟赛总结一下:题目比较简单(我后面一个题目100一个90都是暴力的功/dogen)Frist problem:   总结:一道伪装成5⭐的打卡题目用时:2~3min思路:每......
  • 模拟退火
    核心思路就是模拟物理上的退火过程,有一个初温和末温,和降温系数(每次初温乘以系数),当初温大于末温时,我们随机一个解,并尝试更新当前解,当不大于末温时退火结束。更新的方法:如......
  • 20220823 模拟赛题解
    T1文件压缩DecriptionlinkSolution可以根据\(S'\)和\(p\)求出第一个字符,然后把\(S'\)sort一遍后得到字符串\(T\),那么我们就可以求出每一个字符的前驱和后继,所......
  • 经营模拟类游戏推荐
    今天为大家带来的是Mac平台上一款关于王国发展的游戏王国与城堡Mac版。王国与城堡是游戏是由LionShield所制作发行的经营模拟类游戏,游戏中您需要将一个小村庄慢慢发展成大......
  • NBA 2K22 Arcade Edition for Mac(篮球比赛模拟游戏)
    NBA2K22ArcadeEditionforMac是畅销的NBA2K系列的最新作品,从您最喜欢的NBA球队中进行选择,并在具有更新的2022NBA名册的快速比赛中与竞争对手展开较量。在在线......