多维前缀和的逆运算,只需要对于每一位减除其在这一位上的前缀接收点的答案就可以了。
我们考虑要减去至少有一位不一样的,那我们考虑最后一位是哪一位,然后减除贡献之后多余的贡献就不要计算了。
代码:
#include <bits/stdc++.h>
using namespace std;
const int N = 1111111;
#define int long long
int n , m , x , y , a[N] , c[N] , s = 1;
main(void) {
for(int i = scanf("%lld" , &n) * printf("%lld\n" , n) * 0;i < n;++ i) scanf("%lld" , &a[i]) , printf("%lld " , a[i]);
for(int i = scanf("%lld" , &m) * printf("\n%lld\n" , m) * 0;i < m;++ i) scanf("%lld" , &c[i]); a[n ++] = m;
for(int i = 0;i < n;++ i) if(a[i] - 1) {
for(int j = m - 1;j >= 0;-- j) if(j % (s * a[i]) >= s) c[j] -= c[j - s]; s *= a[i];
if(s >= m) break;
}
for(int i = 0;i < m;++ i) printf("%lld " , c[i]);
}