全排列的价值
题解 动态规划
#include <iostream>
using namespace std;
typedef unsigned long long LL;
const LL MOD = 998244353;
const int N = 1000005;
LL n, ans, cnt;
LL f[N];//只考虑前i个数的情况下的价值之和
LL factor = 1;//n!
int main() {
scanf("%llu", &n);
//f[2] = 1;
LL t3;
for(LL i = 2; i <= n; ++i) {
f[n] = ((i * f[i - 1] % MOD) + ((i - 1) * i / 2) * factor % MOD) % MOD;//除法前不能%MOD
factor = (factor * i) % MOD;
}
printf("%llu", f[n]);
//答案取模
return 0;
}**加粗样式**
注意点
factor 一定要乘在 (i - 1) * i / 2 的后面,因为factor中使用了%MOD,而除法取模需要逆元;若factor不取模,会爆long long
技能升级
题解
法一:优先队列(大根堆) O(M*logM) 可过50%
#include <iostream>
#include <queue>
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int N = 10e5 + 5;
struct node {
LL val;//当前技能升级后获得的点数
int idx;//对应的下标
//一定要用friend,否则要写在全局中
friend bool operator<(const node &n1,const node &n2){
return n1.val < n2.val;
}
};
LL A[N], B[N];
LL ans;
priority_queue<node> que;
int main() {
int n, m;
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; ++i) {
scanf("%lld%lld", &A[i], &B[i]);
que.push({A[i], i});
}
while(m--) {
auto t = que.top();
ans += t.val;
if(t.val - B[t.idx] > 0) {
que.push({t.val - B[t.idx], t.idx});
}
que.pop();
}
printf("%lld", ans);
return 0;
}