洛谷7月月赛 B 题解

洛谷月赛
B
https://www.luogu.com.cn/problem/P7725
题面
初始值为0,n块宝石
每个宝石有属性 op 和 vv,表示:
若 op 为 +,则值会加v;
若 op 为 *,则值会乘v。
希望采取某种镶嵌方式,将每个宝石都镶嵌恰好一遍,且最终值最大
答案对P=998244353取模 即输出(ans % P + P) % P

Algorithm:
该题本质是一个分类讨论的数学题

易知需要提前处理好
'+' 中 正值和f1与负值和f2
'*' 中 总乘积M,

接下来分类讨论:

  1. 若M>0 且 任意op=''时v>0
    则ans =+f1->
    M->+f2
  2. 若M>0 且 存在op=''时v<0
    令最小负乘为minn 则ans =+f1
    minn+f2*剩余因数
  3. 若M<0 则必有op=''时v<0
    则ans =+f2
    minn+f1*剩余因数

需要注意的点:
开long long
乘法取模 m2=(m2%Px%P)%P
因已提前对M取模 所以不可用M/=minn得到剩余因数
需要
minn*M/minn来得到

AC代码

//by 正放的瓶塞
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#define ll long long
#define P 998244353
using namespace std;

ll n,minn=1e6+10,ans=0;
char ch;
ll m1,flag,l1,x,m2=1;

inline void p() {ans%=P;}

inline void print() {
	printf("%lld",(ans % P + P) % P);
}

int main() {
	scanf("%lld",&n);
	
	for (int i=1;i<=n;i++) {
		cin>>ch;
		if (ch=='+') {
			cin>>x;
			if (x<0) {
				l1+=x;
				l1%=P;
			}
			if (x>0) {
				m1+=x;
				m1%=P;
			}
		}
		if(ch=='*') {
			cin>>x;
			m2=(m2%P*x%P)%P;
			if (x<0) {
				flag=1;
				minn=min(abs(x),minn);
			}	
		}
	}
	minn=-minn;
	
	if (m2>0&&!flag) {
		ans+=m1;
		ans=(ans%P*m2%P)%P;
		ans+=l1;
		print();
		return 0;
	}
	
	if (m2>0&&flag) {
		ans+=m1;
		ans=(ans%P*minn%P)%P;
		ans+=l1;
		ans=(ans%P*m2%P)%P;
		ans/=minn;
		print();
		return 0;
	}
	if (m2<0) {
//		m2/=minn;
		ans+=l1;
		ans=(ans%P*minn%P)%P;
		ans+=m1;
		ans=(ans%P*m2%P)%P;
		ans/=minn;
		print();
		return 0;
	}
	
	return 0;
}

上一篇:牛客多校第六场8月2日补题记录


下一篇:redis6.0.5之lzf阅读笔记2--压缩