2 条题解
-
0
首先我们考虑树状数组的结构。会发现a_i 最终一定只会对 a_i 以及 a_i 的祖先节点产生贡献。那么假设有两点 i 以及 i的祖先 j,考虑 i 对 j 会贡献多少次(即节点j包含多少个a[i])。节点j中的每个a[i]都经历了k次 f 操作。这等价于从i开始走 k 步(每次f操作可以选择不动,或者跳到相邻的祖先节点)走到 j的路径总数,直接用插板法解决,答案为C(d+k−1,k−1)=C(d+k-1,d)。
#include <bits/stdc++.h> using namespace std; typedef long long LL; const int N=2e5+10; const LL P=998244353; LL a[N], inv[N]; int main(){ //freopen("a.in", "r", stdin); int T; scanf("%d", &T); inv[0]=inv[1]=1; for(int i=2; i<=N-10; i++) inv[i]=inv[P%i]*(P-P/i)%P; while(T--){ int n, K; scanf("%d%d", &n, &K); for(int i=1; i<=n; i++) scanf("%lld", &a[i]); for(int i=1; i<=n; i++){ LL t=1; for(LL j=i+i&-i, d=1; j<=n; j+=j&-j, d++){ t=t*(d+K-1)%P*inv[d]%P; a[j]=(a[j]-t*a[i]%P+P)%P; } } for(int i=1; i<=n; i++) printf("%lld ", a[i]); printf("\n"); } return 0; } -
0
/* 首先我们考虑树状数组的结构。会发现a_i 最终一定只会对 a_i 以及 a_i 的祖先节点产生贡献。 那么假设有两点 i 以及 i的祖先 j,考虑 i 对 j 会贡献多少次(即节点j包含多少个a[i])。节点j中的每个a[i]都经历了k次 f 操作。 这等价于从i开始走 k 步(每次f操作可以选择不动,或者跳到相邻的祖先节点)走到 j的路径总数,直接用插板法解决,答案为C(d+k−1,k−1)=C(d+k-1,d)。 */ #include<bits/stdc++.h> using namespace std; typedef long long LL; const int N=2e5+10; const LL P=998244353; LL a[N], inv[N]; int main(){ //freopen("a.in", "r", stdin); int T; scanf("%d", &T); inv[0]=inv[1]=1; for(int i=2; i<=N-10; i++) inv[i]=inv[P%i]*(P-P/i)%P; while(T--){ int n, K; scanf("%d%d", &n, &K); for(int i=1; i<=n; i++) scanf("%lld", &a[i]); for(int i=1; i<=n; i++){ LL t=1; for(LL j=i+i&-i, d=1; j<=n; j+=j&-j, d++){ t=t*(d+K-1)%P*inv[d]%P; a[j]=(a[j]-t*a[i]%P+P)%P; } } for(int i=1; i<=n; i++) printf("%lld ", a[i]); printf("\n"); } return 0; }
- 1
信息
- ID
- 2119
- 时间
- 3000ms
- 内存
- 256MiB
- 难度
- 8
- 标签
- 递交数
- 15
- 已通过
- 6
- 上传者