6361. 【NOIP2019模擬2019.9.18】鯧數(pair)

Problem

[L,R][L,R]之間的每個數的逆序對個數之和

Data constraint

L,R10500000L,R\le 10^{500000}

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);
	}
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章