求调
  • 板块P5240 Derivation
  • 楼主bcdmwSjy
  • 当前回复3
  • 已保存回复3
  • 发布时间2025/1/11 22:11
  • 上次更新2025/1/12 12:00:38
查看原帖
求调
514727
bcdmwSjy楼主2025/1/11 22:11

55分,两个点没过(其实是一个,那两个数据好像一样),有没有大佬发一下代码也行啊

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

const int mod=998244353;

ll qpow(ll a,ll b,int mod){
	a%=mod;
	ll res=1;
	for (;b;b>>=1,a=a*a%mod) if (b&1) res=res*a%mod;
	return res;
}

ll phi(ll x){
	ll ans=x;
	for (ll i=2;i*i<=x;i++){
		if (x%i==0){
			ans=ans/i*(i-1);
			do{
				x/=i;
			}while (x%i==0);
		}
	}
	if (x>1) ans=ans/x*(x-1);
	return ans;
}

int _phi[]={998244353,998244352,402653184,134217728,67108864,33554432,16777216,8388608,4194304,2097152,1048576,524288,262144,131072,65536,32768,16384,8192,4096,2048,1024,512,256,128,64,32,16,8,4,2,1};

inline int fphi(int x){
	if (x==1) return 1;
	if (binary_search(_phi,_phi+31,x,greater<int>())){
		return _phi[lower_bound(_phi,_phi+31,x,greater<int>())-_phi+1];
	}
	exit(-2);
	return phi(x);
}

struct Node{
	int type;
	char cdata;
	ll idata;
	Node(){
		type=cdata=idata=0;	
	}
	Node(char c){
		if (c=='x') type=3;
		else{
			type=1;
			cdata=c;	
		}
	}
	Node(ll i){
		type=2;
		idata=i;
	}
	operator char() const{
		// assert(type==1);
		return cdata;
	}
	operator ll() const{
		// assert(type==2);
		return idata;
	}
};

struct Tree{
	int ls,rs;
	Node val;
};

int cnt;
string s;
vector<Node> op,dat;
Tree tr[1000000];

int newNode(Node x){
	tr[++cnt]={0,0,x};
	return cnt;
}

int check(Node x){
	if (x.type==1){
		char c=x.cdata;
		if (c=='+' or c=='-') return 1;
		else if (c=='*' or c=='/') return 2;
		else if (c=='^') return 3;
		else if (c=='(' or c==')') return 0;
	}
	return -1;
}

void print(const vector<Node> &v){
	for (auto i:v){
		if (i.type==3) cout<<"x ";
		else if (i.type==1) cout<<i.cdata<<" ";
		else cout<<i.idata<<" ";
	}
}

void RPN(const string &s){
	for (int i=0;i<s.size();){
		if (isdigit(s[i])){
			ll tmp=0;
			for (;i<s.size() and isdigit(s[i]);i++) tmp=(tmp*10+(s[i]^48));
			dat.push_back(tmp);
		}else if (s[i]=='x'){
			dat.push_back(s[i]);
			i++;
		}else if (s[i]=='('){
			op.push_back(s[i]);
			i++;
		}else if (s[i]==')'){
			char t=op.back();
			while (t!='('){
				op.pop_back();
				dat.push_back(t);
				t=op.back();
			}
			op.pop_back();
			i++;
		}else if (1<=check(s[i]) and check(s[i])<=3){
			if (not op.empty()){
				char t=op.back();
				while (not op.empty() and check(s[i])<=check(t)){
					if (check(s[i])==check(t) and s[i]=='^') break;
					op.pop_back();
					dat.push_back(t);
					if (not op.empty()) t=op.back();
				}
			}
			op.push_back(s[i]);
			i++;
		}
	}
	reverse(op.begin(),op.end());
	op.insert(op.begin(),dat.begin(),dat.end());
}

vector<int> num;

int build(){
	reverse(op.begin(),op.end());
	while (not op.empty()){
		Node t=op.back();
		op.pop_back();
		if (t.type!=1) num.push_back(newNode(t));
		else{
			int x=num.back();
			num.pop_back();
			int y=num.back();
			num.pop_back();
			num.push_back(newNode(t));
			tr[num.back()].ls=y;
			tr[num.back()].rs=x;
		}
	}
	// assert(num.size()==1);
	return num.back();
}

int dfs(int i){
	if (tr[i].val.type==1){
		char t=tr[i].val;
		if (t=='+' or t=='-'){
			int curr=newNode(t);
			tr[curr].ls=dfs(tr[i].ls);
			tr[curr].rs=dfs(tr[i].rs);
			return curr;
		}else if (t=='*'){ // (f(x)g(x))'=f(x)g'(x)+f'(x)g(x)
			int curr=newNode('+');
			tr[curr].ls=newNode('*');
			tr[curr].rs=newNode('*');
			tr[tr[curr].ls].ls=tr[i].ls;
			tr[tr[curr].ls].rs=dfs(tr[i].rs);
			tr[tr[curr].rs].ls=dfs(tr[i].ls);
			tr[tr[curr].rs].rs=tr[i].rs;
			return curr;
		}else if (t=='^'){ // ((f(x))^n)'=n(f(x))^{n-1}f'(x)
			int curr=newNode('*');
			tr[curr].ls=newNode('*');
			tr[tr[curr].ls].ls=tr[i].rs;
			tr[tr[curr].ls].rs=newNode('^');
			tr[tr[tr[curr].ls].rs].ls=tr[i].ls;
			tr[tr[tr[curr].ls].rs].rs=newNode('~');
			tr[tr[tr[tr[curr].ls].rs].rs].ls=tr[i].rs;
			// tr[tr[tr[tr[curr].ls].rs].rs].rs=newNode(Node(1ll));
			tr[curr].rs=dfs(tr[i].ls);
			return curr;
		}
	}else if (tr[i].val.type==2){ // c
		return newNode(Node(0ll));
	}else if (tr[i].val.type==3){ // x
		return newNode(Node(1ll));
	}
	assert(false);
	__builtin_unreachable();
}

pair<ll,bool> eval(int i,ll x,int p){
	assert(i!=0);
	if (p==1) return {0,1};
	if (tr[i].val.type==1){
		char t=tr[i].val;
		if (t=='+'){
			auto [ansl,fl]=eval(tr[i].ls,x,p);
			auto [ansr,fr]=eval(tr[i].rs,x,p);
			return {(ansl+ansr)%p,fl or fr or ansl+ansr>=p};
		}else if (t=='~'){
			auto [ansl,fl]=eval(tr[i].ls,x,p);
			return {(ansl-1+p)%p,fl};
		}else if (t=='*'){
			auto [ansl,fl]=eval(tr[i].ls,x,p);
			auto [ansr,fr]=eval(tr[i].rs,x,p);
			return {ansl*ansr%p,fl or fr or ansl*ansr>=p};
		}else if (t=='^'){
			int t=fphi(p);
			auto [ansl,fl]=eval(tr[i].ls,x,p);
			if (ansl==1 and not fl) return {1,0};
			auto [ansr,fr]=eval(tr[i].rs,x,t);
			if (ansr==0 and not fr) return {1,0};
			if (ansl==0 and not fl) return {0,0};
			if (ansr==1 and not fr) return {ansl,fl};
			if (fr) ansr+=t;
			return {qpow(ansl,ansr,p),fl or pow(ansl,ansr)>=p};
		}
	}else if (tr[i].val.type==2){ // c
		return {tr[i].val.idata%p,tr[i].val.idata>=p};
	}else if (tr[i].val.type==3){ // x
		return {x%p,x>=p};
	}
	assert(false);
	__builtin_unreachable();
}

void print(int i){
	if (i){
		print(tr[i].ls);
		if (tr[i].val.type==1) cout<<tr[i].val.cdata<<" ";
		else if (tr[i].val.type==2) cout<<tr[i].val.idata<<" ";
		else cout<<"x ";
		print(tr[i].rs);
	}
}

int main(){
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	cout.tie(nullptr);
	int T;
	cin>>T;
	while (T--){
		cnt=0;
		op.clear();
		num.clear();
		dat.clear();
		ll x1,x2;
		cin>>s>>x1>>x2;
		RPN(s);
		int rt=build();
		rt=dfs(rt);
		// print(rt);
		// cout<<"*****\n";
		cout<<eval(rt,x1,mod).first<<" "<<eval(rt,x2,mod).first<<"\n";
	}
	return 0;
}
2025/1/11 22:11
加载中...