Problem
求 [ L , R ] [L,R] [L,R]之间的每个数的逆序对个数之和
Data constraint
L , R ≤ 1 0 500000 L,R\le 10^{500000} L,R≤10500000
Solution
看了五分钟就会做了,直接模拟即可。
但是打了很久,下次遇到这种稍微需要一点时间和耐心的题要先仔细思考一下,把问题想清楚了再打,不要边打边调,效率很低。
Code
#include <bits/stdc++.h>
#define F(i, a, b) for (int i = a; i <= b; i ++)
#define G(i, a, b) for (int i = a; i >= b; i --)
#define max(a, b) ((a) > (b) ? (a) : (b))
#define min(a, b) ((a) < (b) ? (a) : (b))
#define mx(a, b) ((a) = max(a, b))
#define mn(a, b) ((a) = min(a, b))
#define mem(a, b) memset(a, b, sizeof a)
#define mec(a, b) memcpy(a, b, sizeof a)
#define pf printf
#define add(a, b) ((a) = (a + b) % Mo)
using namespace std;
#define get getchar()
void Re(int &x) {
char c = get; x = 0 ;
for (; !isdigit(c); c = get);
for (; isdigit(c); x = (x << 3) + (x << 1) + c - '0', c = get);
}
const int N = 5e5 + 10;
const int Mo = 998244353;
int T, I, a[N];
long long C[10], D[10], ten[N], sum[N];
char L[N], R[N];
int Solve(int Len, char *s, int ad) {
int Ans = 0;
F(i, 1, Len) a[i] = s[i] - '0';
a[Len] -= ad;
for (int i = Len; i > 0 && a[i] < 0; a[i - 1] --, a[i] += 10, i --);
if (a[1] == 0) {
F(i, 1, Len - 1)
a[i] = a[i + 1];
Len --;
}
int cnt = 0; mem(C, 0), mem(D, 0);
F(i, 1, Len) {
if (a[i])
add(Ans, 1ll * a[i] * sum[Len - i] % Mo); // b[i] = 0..a[i]-1 calc(i+1~Len)itself
if (i < Len)
F(j, 1, a[i] - 1)
add(Ans, 1ll * j * (Len - i) % Mo * ten[Len - i - 1] % Mo); // b[i] = j(0..a[i]-1) calc(i > j)
add(Ans, 1ll * a[i] * cnt % Mo * ten[Len - i] % Mo); // b[i] = 0..a[i]-1 calc(i__ > i_)
F(j, 1, 9)
add(Ans, 1ll * (D[j] + C[j]) * min(j, a[i]) * ten[Len - i] % Mo); // b[i_] = j b[i] = min(j, a[i] - 1)
// F(j, 0, a[i - 1] - 1)
// add(Ans, (j + 1) * ten[Len - i]);
F(j, a[i] + 1, 9)
add(Ans, 1ll * (j - a[i]) * C[j] * ten[Len - i] % Mo);
F(j, a[i] + 1, 9) cnt = cnt + D[j], cnt = cnt > Mo ? cnt - Mo : cnt;
F(j, 1, 9)
C[j] = (1ll * C[j] * 10 + 1ll * a[i] * D[j]) % Mo;
D[a[i]] ++;
if (D[a[i]] >= Mo) D[a[i]] -= Mo;
}
return Ans + cnt;
}
int main() {
freopen("pair.in", "r", stdin);
freopen("pair.out", "w", stdout);
Re(T), Re(I);
ten[0] = 1;
F(i, 1, N - 10) ten[i] = ten[i - 1] * 10LL % Mo;
F(i, 2, N - 10) {
sum[i] = sum[i - 1] * 10;
F(j, 1, 9)
add(sum[i], 1ll * j * (i - 1) % Mo * ten[i - 2] % Mo);
}
F(i, 1, T) {
scanf("%s %s", L + 1, R + 1);
int len1 = strlen(L + 1);
int len2 = strlen(R + 1);
pf("%d\n", (Solve(len2, R, 0) - Solve(len1, L, 1) + Mo) % Mo);
}
}