洛谷月赛
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,
接下来分类讨论:
- 若M>0 且 任意op=''时v>0
则ans =+f1->M->+f2 - 若M>0 且 存在op=''时v<0
令最小负乘为minn 则ans =+f1minn+f2*剩余因数 - 若M<0 则必有op=''时v<0
则ans =+f2minn+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;
}