QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#828914 | #4492. Yet Another Easy Permutation Count Problem | ereoth | AC ✓ | 2822ms | 58396kb | C++14 | 3.1kb | 2024-12-23 21:59:00 | 2024-12-23 21:59:01 |
Judging History
answer
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define int long long
using namespace std;
const int kmax = 1e6 + 3;
const int Mod = 998244353;
int t, n, m;
int s[kmax];
int pos[kmax];
long long fac[kmax];
struct Fenwick {
long long c[kmax];
int Lowbit(int x) {
return x & -x;
}
void Modifyup(int x, long long v) {
for(; x <= n; x += Lowbit(x)) {
c[x] = (c[x] + v) % Mod;
}
}
void Modifydown(int x, long long v) {
for(; x; x -= Lowbit(x)) {
c[x] = (c[x] + v) % Mod;
}
}
long long Getresup(int x) {
long long tot = 0;
for(; x <= n; x += Lowbit(x)) {
tot = (tot + c[x]) % Mod;
}
return tot;
}
long long Getresdown(int x) {
long long tot = 0;
for(; x; x -= Lowbit(x)) {
tot = (tot + c[x]) % Mod;
}
return tot;
}
void Clear() {
for(int i = 1; i <= n; i++) c[i] = 0;
}
} fw[4];
long long C(long long x, long long y) {
if(y == 2) return x * (x - 1) / 2 % Mod;
return x * (x - 1) / 2 * (x - 2) / 3 % Mod;
}
long long Fac(long long x) {
if(x < 0) return 0;
return fac[x];
}
long long Sum(int l, int r) {
if(l > r) return 0;
return s[r] - s[l - 1];
}
void Solve() {
cin >> n >> m;
for(int i = 0; i < 4; i++) fw[i].Clear();
for(int i = 1; i <= n; i++) s[i] = 1, pos[i] = 0;
for(int i = 1, x, y; i <= m; i++) {
cin >> x >> y;
pos[x] = y;
s[y] = 0;
}
for(int i = 1; i <= n; i++) s[i] += s[i - 1];
fac[0] = 1;
for(int i = 1; i <= n; i++) fac[i] = fac[i - 1] * i % Mod;
long long res = 0;
long long sw = 0;
for(int i = 2, zero = 0; i <= n; i++) {
int x = pos[i - 1], y = pos[i];
if(!x && !y) {
res = (res + C(s[n], 2) * Fac(s[n] - 2) % Mod) % Mod;
res = (res + 1ll * zero * C(s[n], 3) % Mod * Fac(s[n] - 3) % Mod);
res = (res + sw * Fac(s[n] - 2) % Mod) % Mod;
} else if(!x) {
int ss = Sum(y, n);
res = (res + ss * Fac(s[n] - 1) % Mod) % Mod;
res = (res + (fw[2].Getresdown(n) - fw[2].Getresdown(y)) * Fac(s[n] - 1) % Mod) % Mod;
res = (res + 1ll * zero * C(ss, 2) % Mod * Fac(s[n] - 2) % Mod) % Mod;
} else if(!y) {
int ss = Sum(1, x);
res = (res + ss * Fac(s[n] - 1) % Mod) % Mod;
res = (res + fw[1].Getresdown(x - 1) * Fac(s[n] - 1) % Mod) % Mod;
res = (res + 1ll * zero * C(ss, 2) % Mod * Fac(s[n] - 2) % Mod) % Mod;
} else if(x > y) {
int ss = Sum(y, x);
res = (res + Fac(s[n])) % Mod;
res = (res + 1ll * zero * ss % Mod * Fac(s[n] - 1) % Mod) % Mod;
res = (res + 1ll * (fw[0].Getresdown(x) - fw[0].Getresdown(y - 1)) * Fac(s[n]) % Mod) % Mod;
}
if(pos[i - 1]) {
sw = (sw + 1ll * Sum(1, pos[i - 1]) * Sum(pos[i - 1], n) % Mod) % Mod;
fw[0].Modifyup(pos[i - 1], 1);
fw[1].Modifyup(pos[i - 1], Sum(1, pos[i - 1]));
fw[2].Modifyup(pos[i - 1], Sum(pos[i - 1], n));
} else {
zero++;
}
}
cout << res << '\n';
}
signed main() {
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
cin >> t;
while(t--) Solve();
return 0;
}
詳細信息
Test #1:
score: 100
Accepted
time: 2822ms
memory: 58396kb
input:
100 1 1 1 1 7513 7311 5538 3089 3928 1029 5512 3849 100 1643 7328 4748 5811 196 6557 2258 3348 790 2760 882 1297 689 7500 6955 3619 3686 3724 3401 6412 4691 6471 4947 6315 5754 1752 1086 2648 124 6721 2929 7185 5179 7239 6148 3005 7383 6676 3884 3074 6165 5062 5842 1145 5090 7376 848 5418 6441 275 6...
output:
0 89541616 367554988 216909100 990456909 526769607 506026027 780187494 553834792 144362048 842584375 861132490 730089994 250057476 295193259 96890952 451932499 132980145 430587965 19967698 589057985 811887276 759432199 345092973 588708812 875024174 665937616 34601572 507128381 479135581 798327226 74...
result:
ok 100 lines