24分建树 MLE 求调(有注释)
查看原帖
24分建树 MLE 求调(有注释)
1068165
InfiniteRobin楼主2024/10/13 18:49

记录

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int m,q;

struct node{
	char lo;
	ll num,tid,fid;
}a[500005];

int getpos(string s){  //找当前三目运算冒号的位置 
	int cnt1=0,cnt2=0;
	for(int i=0;i<s.size();i++){
		if(s[i]=='?'){
			cnt1++;
		}
		if(s[i]==':'){
			cnt2++;
		}
		if(cnt1==cnt2&&cnt1!=0) return i;
	}
}

ll turnnum(string s){ //字符串转数字 
	ll ans=0;
	for(int i=0;i<s.size();i++){
		ans=ans*10+s[i]-'0';
	}
	return ans;
}

ll solve(ll x,int p){
	if(a[p].lo=='n'||a[p].tid==0||a[p].fid==0){  //直接返回 
		return a[p].num;
	}
	if(a[p].lo=='b'){  //如果是大于号 
		if(x>a[p].num){  //满足 
			return solve(x,a[p].tid);  //走冒号前面的 
		}
		else{
			return solve(x,a[p].fid); //走冒号后面的 
		}
	}
	if(a[p].lo=='s'){  //小于号,同上 
		if(x>a[p].num){
			return solve(x,a[p].fid);  //反过来 
		}
		else{
			return solve(x,a[p].tid);
		}
	}
}

int cnt=0;  //计数器 
void build(string s){  //建树 
	cnt++;
	if(s[0]=='x'){  //如果是三目运算 
		if(s[1]=='>'){  //大于 
			a[cnt].lo='b';	
		}
		else if(s[1]=='<'){  //小于 
			a[cnt].lo='s';
		}
		int pos=s.find('?'),pos2=getpos(s);  //三目运算 问号 & 冒号的位置 
		int nowpos=cnt;  //记录一下 
		a[cnt].num=turnnum(s.substr(2,pos-2)); //整数部分 
		a[cnt].tid=cnt+1; //记录一下子节点编号 
		build(s.substr(pos+1,pos2-pos-1)); //递归 ?~: 这部分 
		a[nowpos].fid=cnt+1; //记录另一个子节点编号 
		build(s.substr(pos2+1,s.size()-pos2-1)); //递归 冒号后边的 
		return;
	}
	else{
		a[cnt].lo='n';  //如果是数字 
		a[cnt].num=turnnum(s); 
		return;
	}
}


int main(){
	//freopen("expr1.in","r",stdin);
	string s;
	cin>>m>>q;
	cin>>s;
	build(s);

	while(q--){
		ll x;
		cin>>x;
		cout<<solve(x,1)<<"\n";
	}
	
}
2024/10/13 18:49
加载中...