2 条题解

  • 0
    @ 2025-10-8 17:00:07

    首先我们考虑树状数组的结构。会发现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
      @ 2025-10-8 16:59:54
      /* 
      首先我们考虑树状数组的结构。会发现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
      上传者