三目运算 8pts 求调
  • 板块学术版
  • 楼主wwwidk1234
  • 当前回复4
  • 已保存回复4
  • 发布时间2024/10/13 12:19
  • 上次更新2024/10/13 14:05:39
查看原帖
三目运算 8pts 求调
728483
wwwidk1234楼主2024/10/13 12:19

https://www.luogu.com.cn/record/181804059

#include<bits/stdc++.h>
using namespace std;
int m,q,n,idx=0;
constexpr int N=1e6+7;
string s;
struct tree
{
	int x,a;  //x=1大于 x=-1 小于 x=0 常数 
	int ls,rs;
}tr[N];
vector<string> res;
inline void split(string s)
{
	string tmp;
	for(char c:s)
	{
		if(c=='?')
		{
			res.push_back(tmp);
			res.push_back("?");
			tmp.clear();
		}
		else if(c==':')
		{
			res.push_back(tmp);
			res.push_back(":");
			tmp.clear();
		}
		else tmp.push_back(c);
	}
	res.push_back(tmp);
}
inline int to_int(string s)
{
	int res=0;
	for(char c:s) res=(res<<3)+(res<<1)+(c^48);
	return res;
}
void build(int l,int r,int u,bool R) //R=0左结点 R=1右结点 
{
//	if(l>r) l=r;
	if(l<0||r>n) return;
	idx++;
//	cerr<<idx<<':'<<l<<' '<<r<<' '<<u<<'R'<<R<<endl;
	if(R==0) tr[u].ls=idx;
	else tr[u].rs=idx;
	if(l>=r||isdigit(res[l][0])) //叶子结点
	{
		tr[idx]={0,to_int(res[l]),-1,-1};
		return;
	}
	else
	{
		string s1=res[l].substr(2);
		if(res[l][1]=='>') tr[idx].x=1;
		else tr[idx].x=-1;
		tr[idx].a=to_int(s1);
		int stk=1,mid=-1;
		for(int i=l+2;i<=r;i++) //找左右孩子分割点
		{
			if(res[i]=="?") stk++;
			if(res[i]==":") stk--;
			if(stk==0)
			{
				mid=i;
				break;
			}
		}
		assert(mid!=-1);
		int pa=idx;
		build(l+2,mid-1,pa,0);
		build(mid+1,r,pa,1);
	}
}
inline bool op(int x,int a,int v)
{
	if(x==1) return v>a;
	else if(x==-1) return v<a;
	else assert(0);
}
int query(int x,int u)
{
//	if(x==12) cerr<<x<<' '<<tr[u].a<<'\n';
	if(tr[u].x==0) return tr[u].a;
	if(op(tr[u].x,tr[u].a,x)) query(x,tr[u].ls);
	else query(x,tr[u].rs);
}
inline void sub1()
{
	int a,l,r;
	a=to_int(res[0].substr(2));
	l=to_int(res[2]);
	r=to_int(res[4]);
	while(q--)
	{
		int x;
		cin>>x;
		if(s[1]=='<') cout<<(x<a?l:r)<<'\n';
		else cout<<(x>a?l:r)<<'\n';
	}
}
inline bool isSub1()
{
	return res.size()==5;
}
int main()
{
//	freopen("expr3.in","r",stdin);
//	freopen("expr.out","w",stdout);
	scanf("%d%d",&m,&q);
	cin>>s;
	split(s);
	if(isdigit(s[0]))
	{
		while(q--) cout<<s<<'\n';
		return 0;
	}
	else if(isSub1())
	{	
		sub1();
		return 0;
	}
//	for(auto C:res) cout<<C<<' ';
	n=res.size()-2;
	build(0,n,idx,0);
//	for(int u=1;u<=idx;u++) cerr<<u<<' '<<tr[u].x<<' '<<tr[u].a<<' '<<tr[u].ls<<' '<<tr[u].rs<<endl;
	while(q--)
	{
		int x;
		scanf("%d",&x);
		printf("%d\n",query(x,1));
	}
	return 0;
}
2024/10/13 12:19
加载中...