P9129 [USACO23FEB] Piling Papers G
先考虑一次询问怎么做。首先容斥成
一个朴素的想法是设
这给我们一些启示:在设计状态的时候,我们不能让
设
于是我们得到了一个
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 3e2 + 5, M = 20, mod = 1e9 + 7;
int n, m, q, a[N], lim[M], ansL[N][N], ansR[N][N], f[M][M][3]; LL L, R;
void getlim(LL x) {
m = 0;
while (x > 0) lim[++m] = x % 10, x = x / 10;
reverse(lim + 1, lim + m + 1);
}
int chk(int a, int b) {
if (a < b) return 0;
else if (a == b) return 1;
else return 2;
}
int main() {
ios :: sync_with_stdio(false);
cin.tie(nullptr);
cin >> n >> L >> R;
for (int i = 1; i <= n; i++) cin >> a[i];
getlim(L - 1);
for (int i = 1; i <= n; i++) {
memset(f, 0, sizeof(f));
for (int j = i; j <= n; j++) {
for (int x = 1; x <= m; x++) {
for (int y = m; y > x; y--) {
if (a[j] > lim[x]) {
for (int k = 0; k <= 2; k++) f[x][y][2] = (f[x][y][2] + f[x + 1][y][k]) % mod;
} else if (a[j] == lim[x]) {
for (int k = 0; k <= 2; k++) f[x][y][k] = (f[x][y][k] + f[x + 1][y][k]) % mod;
} else {
for (int k = 0; k <= 2; k++) f[x][y][0] = (f[x][y][0] + f[x + 1][y][k]) % mod;
}
f[x][y][2] = (f[x][y][2] + f[x][y - 1][2]) % mod;
f[x][y][chk(a[j], lim[y])] = (f[x][y][chk(a[j], lim[y])] + f[x][y - 1][1]) % mod;
f[x][y][0] = (f[x][y][0] + f[x][y - 1][0]) % mod;
}
}
for (int x = 1; x <= m; x++) f[x][x][chk(a[j], lim[x])] = (f[x][x][chk(a[j], lim[x])] + 2) % mod;
for (int x = 1; x <= m; x++) {
ansL[i][j] = (ansL[i][j] + f[x][m][1]) % mod;
ansL[i][j] = (ansL[i][j] + f[x][m][0]) % mod;
if (x > 1) ansL[i][j] = (ansL[i][j] + f[x][m][2]) % mod;
}
}
}
getlim(R);
for (int i = 1; i <= n; i++) {
memset(f, 0, sizeof(f));
for (int j = i; j <= n; j++) {
for (int x = 1; x <= m; x++) {
for (int y = m; y > x; y--) {
if (a[j] > lim[x]) {
for (int k = 0; k <= 2; k++) f[x][y][2] = (f[x][y][2] + f[x + 1][y][k]) % mod;
} else if (a[j] == lim[x]) {
for (int k = 0; k <= 2; k++) f[x][y][k] = (f[x][y][k] + f[x + 1][y][k]) % mod;
} else {
for (int k = 0; k <= 2; k++) f[x][y][0] = (f[x][y][0] + f[x + 1][y][k]) % mod;
}
f[x][y][2] = (f[x][y][2] + f[x][y - 1][2]) % mod;
f[x][y][chk(a[j], lim[y])] = (f[x][y][chk(a[j], lim[y])] + f[x][y - 1][1]) % mod;
f[x][y][0] = (f[x][y][0] + f[x][y - 1][0]) % mod;
}
}
for (int x = 1; x <= m; x++) f[x][x][chk(a[j], lim[x])] = (f[x][x][chk(a[j], lim[x])] + 2) % mod;
for (int x = 1; x <= m; x++) {
ansR[i][j] = (ansR[i][j] + f[x][m][1]) % mod;
ansR[i][j] = (ansR[i][j] + f[x][m][0]) % mod;
if (x > 1) ansR[i][j] = (ansR[i][j] + f[x][m][2]) % mod;
}
}
}
cin >> q;
while (q--) {
int l, r; cin >> l >> r;
int ans = (ansR[l][r] - ansL[l][r] + mod) % mod;
cout << ans << "\n";
}
return 0;
}