首页 > 其他分享 >GYM100198G - PL/Cool

GYM100198G - PL/Cool

时间:2023-05-15 21:15:28浏览次数:41  
标签:cnt return fa int res GYM100198G solve PL Cool

比较毒瘤的一道模拟。

首先,我们考虑如何处理 define,我们发现,其中不会出现环,并且所有冲突的定义以第一个为准,那么就想到并查集,将 \(x\) 的父亲定成 \(y\)。只不过我们平时的并查集是无向的,这里是有向的,也就是谁是根是重要的。

我们先给所有的定义和被定义的变量映射到一个值,然后用并查集维护,如果当前节点已经有父亲,或者 \(y\) 在 \(x\) 的子树中,就不连边。否则连边。

然后考虑计算答案。我们考虑中缀表达式。每次处理出当前第一个需要处理的符号,将原串划分成两个子问题递归计算。但是注意我们要按顺序进行,左边的优先级高,那么就从右边开始往下递归查找。反之亦然。递归直到没有运算符号。

同时,因为括号的优先级最高,所以我们维护当前递归了几层括号,在括号内部的运算忽略。如果整个子串被一个括号包含,要去掉。

我们先查找 +-,注意它们也有可能不是代数和符号而是表示正负号,这个时候要判断前面的字符是否是运算来判别。

然后是 */%。注意负数取模的定义,这道题是绝对值为绝对值取模,符号为二者符号相乘。

最后是 ^,最好写一个快速幂,而且只有它是从前往后的。

别忘了处理掉作为符号的 +-,对最终的变量,如果表中有就直接找到它的值输出(注意在并查集上跑出父亲)。如果表中没有就临时转 int,也不要存表,否则表长不好控制。注意判断含不含字母,如果是新变量要赋成 0

最后,大小写不敏感,可以把所有的字母输入之后统一成小写。输入也比较扯,因为表达式带空格。我是用的 getline 一次读入,然后用 stringstream 搞掉空格。

map<string,int>id;
string ss[60005];
int fa[60005],val[60005],cnt=0;
inline int sti(string s){
	int ans=0;
	for(auto i:s){
		if((i<'0'||i>'9'))return 0;
		ans=ans*10+i-'0';
	}
	return ans;
}
inline void add(string s){
	if(!id.count(s)){
		id[s]=++cnt;
		ss[cnt]=s;val[cnt]=sti(s);
	}
}
inline int head(int x){
	return fa[x]?fa[x]=head(fa[x]):x;
}
inline int fpow(int x,int p){
	if(!p)return 1;
	int res=fpow(x,p>>1);
	if(p&1)return res*res*x;
	return res*res;
}
inline int mymod(int x,int y){
	if((x<0)^(y<0))return -abs(x)%abs(y);
	return abs(x)%abs(y);
}string s;
inline bool sig(int x){
	return (s[x]=='+'||s[x]=='-'||s[x]=='*'||s[x]=='/'||s[x]=='%'||s[x]=='^');
}
inline int solve(int l,int r){
	for(int i=r,cnt=0;i>l;i--){
		cnt+=(s[i]==')')-(s[i]=='(');
		if(!cnt){
			if(s[i]=='+'&&!sig(i-1))return solve(l,i-1)+solve(i+1,r);
			if(s[i]=='-'&&!sig(i-1))return solve(l,i-1)-solve(i+1,r);
		}
	}for(int i=r,cnt=0;i>l;i--){
		cnt+=(s[i]==')')-(s[i]=='(');
		if(!cnt){
			if(s[i]=='*')return solve(l,i-1)*solve(i+1,r);
			if(s[i]=='/')return solve(l,i-1)/solve(i+1,r);
			if(s[i]=='%')return mymod(solve(l,i-1),solve(i+1,r));
		}
	}for(int i=l,cnt=0;i<r;i++){
		cnt+=(s[i]=='(')-(s[i]==')');
		if(!cnt){
			if(s[i]=='^')return fpow(solve(l,i-1),solve(i+1,r));
		}
	}if(s[l]=='(')return solve(l+1,r-1);
	if(s[l]=='+')return solve(l+1,r);
	if(s[l]=='-')return -solve(l+1,r);
	st t=s.substr(l,r-l+1);
	if(!id.count(t))return sti(t);
	return val[head(id[t])];
}
string ope,x,y;
signed main(){
	freopen("plcool.in","r",stdin);
	freopen("plcool.out","w",stdout);
	ios::sync_with_stdio(false);
	cin.tie(0);
	while(cin>>ope){
		if(ope=="define"){
			cin>>x>>y;
			for(auto &i:x)if(isupper(i))i-='A',i+='a';
			for(auto &i:y)if(isupper(i))i-='A',i+='a';
			add(x);add(y);
			int a=id[x],b=id[y];
			if(!fa[a]&&head(b)!=a)fa[a]=b;
		}else if(ope=="print"){
			x="";
			getline(cin,s);
			istringstream ss(s);
			while(ss>>y)x+=y;s=x;
			for(auto &i:s)if(isupper(i))i-='A',i+='a';
			cout<<solve(0,(int)s.size()-1)<<endl;
		}else exit(-1);
	}
	return 0;
}
//Crayan_r

标签:cnt,return,fa,int,res,GYM100198G,solve,PL,Cool
From: https://www.cnblogs.com/jucason-xu/p/17403124.html

相关文章

  • 以点类Point及平面图形类Plane为基础设计圆类Circle
    以点类Point及平面图形类Plane为基类公有派生圆类Circle,main(void)函数完成对其的测试。Point类结构说明: Point类的数据成员包括:①私有数据成员:X坐标x(double型),Y坐标y(double型)。Point类成员函数包括:①有参构造函数Point(double,double)和拷贝构造函数Point(constPoin......
  • MySQL高级——Explain信息中rows字段解释
    一、Explain信息中rows字段解释根据表统计信息及索引选用情况,大致估算出找到所需要的记录所需要读取的行数(即每张表有多少行被优化器查询),所需读取的行数越少越好。二、Explain信息中rows字段解释的示例1、没建立索引之前,rows字段表示需要从t2表读取640行数据(即t2表有640行被优化器......
  • element-plus + VUE3 项目 build 之后 el-cascader无法选中而且导致整个网页卡顿
    cascader不能用v-model接收值,需要改为model-value方式<el-cascadermodel-value="selRegion":options="RegionTreeCascader":show-all-levels="true"separator="-":props="{checkStrictly:true,expandTrigger:'hove......
  • Spring的PropertyPlaceholderConfigurer应用
    1.PropertyPlaceholderConfigurer是个bean工厂后置处理器的实现,也就是BeanFactoryPostProcessor接口的一个实现。PropertyPlaceholderConfigurer可以将上下文(配置文件)中的属性值放在另一个单独的标准javaProperties文件中去。在XML文件中用${key}替换指定的properties文件中的值......
  • Laplace变换
    拉普拉斯变换笔记摘录于悍将吴老二的视频关于拉氏变换这个视频就够了一、引入概念求解下面的方程会有困难,因为含有\(x(t)\)的导数项。\[\dot{x}(t)+3x(t)=0\]但是可以通过\(Laplace\)变换来转化为下面的式子,求解\(x(s)\)就会变得简单。\[sx(s)-x(0)+3x(s)=0\]原理解......
  • 【论文翻译-RL×Diffusion】Planning with Diffusion for Flexible Behavior Synthesi
    PlanningwithDiffusionforFlexibleBehaviorSynthesis可视化:https://diffusion-planning.github.io/SergeyLevine组的大作,中了ICML2022年的longtalk。究竟是大佬整活,还是将扩散模型用于强化学习的开山之作呢?翻译可能有问题的地方,以原文为准(狗头)。摘要基于模型的强......
  • 一图看懂CodeArts Deploy 5大特性,带你玩转部署服务
    华为云持续部署服务CodeArtsDeploy,通过模块化自由编排部署流程,实现软件的自动化部署,基于其易入门、功能全、集成度高、自动化、可靠的部署能力,能够帮您快速实现业务上云,全面提升软件的交付效率,显著提升交付质量! 产品详情地址:部署CodeArtsDeploy_一键部署到云主机和容器_多种部署......
  • Explain执行计划key_len详解
    我们在使用Explain查看SQL执行计划时,其中有一列为key_kenEXPLAINselect*FROMuserWHEREid=1;key_len表示使用的索引长度,key_len可以衡量索引的好坏,key_len越小索引效果越好,那么key_len的长度是如何计算的?常见的列类型长度计算:CREATETABLE`user`(`id`bigint......
  • JiaoZiVideoPlayer 监听播放按钮
    jZVideoPlayerStandard.startButton.setOnClickListener(newView.OnClickListener(){@OverridepublicvoidonClick(Viewview){Toast.makeText(mContext,"播放",Toast.LENGTH_SHORT).show();......
  • 如何安全退出已调用多个Activity的Application
    如何安全退出已调用多个Activity的Application?思路如下:建一个工具类,在里面管理activity的添加,移除和退出app的操作;第一步,创建一个名字为ActivityManage的工具类,里面有添加activity,移除activity和退出activity的方法,代码如下:publicclassActivityManage{publ......