Description:
、
题解:
做法1:
一行一行的看。
每次变换相当于乘上多项式(bx+a)。
所以可以搞出 (bx+a)−(p−1) ( b x + a ) − ( p − 1 )
乘第p行的数就可以还原出第一行,之后的用个组合数搞搞就行了。
(bx+a)−(p−1) ( b x + a ) − ( p − 1 ) 的话,只用n项就可以了,并不用全部。
可以先把bx+a求逆,然后快速幂,O(n log^2 n)看上去有点悬。
也可以用二次项展开求出 (bx+a)(p−1) ( b x + a ) ( p − 1 ) 先,再求逆,这个就只用 O(n log n) O ( n l o g n ) 。
做法2:
x>=p很简单,要考虑x < < <script type="math/tex" id="MathJax-Element-5"><</script>p怎么做。
重写一下方程,变成倒推的。
fi,j=(fi+1,j−fi,j−1∗b)/a
f
i
,
j
=
(
f
i
+
1
,
j
−
f
i
,
j
−
1
∗
b
)
/
a
=fi+1,j/a+fi,j−1∗(−b/a)
=
f
i
+
1
,
j
/
a
+
f
i
,
j
−
1
∗
(
−
b
/
a
)
这个可以再推一下方案数,类似于挡板问题。
Code:
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
#define fo(i, x, y) for(int i = x; i <= y; i ++)
#define fd(i, x, y) for(int i = x; i >= y; i --)
#define min(a, b) ((a) < (b) ? (a) : (b))
#define max(a, b) ((a) > (b) ? (a) : (b))
using namespace std;
const int N = 1e7, M = 1e5, C = N + M;
const ll mo = 998244353;
int m, n, a, b, p, Q, x, y;
ll c[M + 5], d[M + 5], fac[C + 5], nif[C + 5], ans;
ll ca[C + 5], cb[M + 5], na[C + 5], nb[M + 5];
ll cc[M + 5];
ll ksm(ll x, ll y) {
ll s = 1;
for(; y; y /= 2, x = x * x % mo)
if(y & 1) s = s * x % mo;
return s;
}
ll Ci(ll a, ll b) { return fac[a] * nif[b] % mo * nif[a - b] % mo;}
int main() {
freopen("table.in", "r", stdin);
freopen("table.out", "w", stdout);
fac[0] = 1; fo(i, 1, C) fac[i] = fac[i - 1] * i % mo;
nif[0] = 1; nif[C] = ksm(fac[C], mo - 2);
fd(i, C - 1, 1) nif[i] = nif[i + 1] * (i + 1) % mo;
scanf("%d %d %d %d %d %d", &m, &n, &a, &b, &p, &Q);
ca[0] = cb[0] = 1; ca[1] = a; cb[1] = b;
na[0] = nb[0] = 1; na[1] = ksm(a, mo - 2); nb[1] = ksm(b, mo - 2);
fo(i, 2, C) ca[i] = ca[i - 1] * ca[1] % mo, na[i] = na[i - 1] * na[1] % mo;
fo(i, 2, M) cb[i] = cb[i - 1] * cb[1] % mo, nb[i] = nb[i - 1] * nb[1] % mo;
cc[0] = 1; cc[1] = (ll) (mo - b) * ksm(a, mo - 2) % mo;
fo(i, 2, M) cc[i] = cc[i - 1] * cc[1] % mo;
fo(i, 1, n) scanf("%lld", &c[i]);
for(; Q; Q --) {
scanf("%d %d", &x, &y);
if(x == p) {
printf("%lld\n", c[y]);
} else
if(x < p) {
int u = p - x;
ans = 0;
fo(i, 1, y) ans += c[i] * Ci(u + (y - i) - 1, u - 1) % mo * na[u] % mo * cc[y - i] % mo;
printf("%lld\n", ans % mo);
} else {
int u = x - p;
ans = 0;
fo(i, max(1, y - u), y)
ans += c[i] * Ci(u, y - i) % mo * cb[y - i] % mo * ca[u - (y - i)] % mo;
printf("%lld\n", ans % mo);
}
}
}