CF1967C:Fenwick Tree 题解

CF1967C:

题意: f(a) 表示 a 数列的树状数组序列,已知 b=f(a)k,输入 k 和 b 数列,求 a 数列。


咕了好久才补的题,并不难,但是有一些启发性的知识可以分享。比赛时我发现树状数组的转移矩阵很稀疏,于是没想那么多就开始模拟矩阵乘,TLE了,后来仔细算了下发现是 nlog3n 的复杂度。


Solution:

树状数组是二叉树吗,显然不是。(但有些初学者误以为是二叉树,因为它名字叫二叉索引树)

我们画出两层树状数组来:

在单层树状数组中,每个方点的值维护的是儿子们的和。

反过来看,就是每个圆点的值会沿着线向祖先节点转移,并且它的值只会转移给最多 log 个祖先结点。

当单层树状数组变成了双层,我们依然可以画出这样的转移路径来,这时圆点到方点的每一条路径,都是数列 a 的贡献转移给 b 的方案。

上图中 a[3] 转移到 b[8] 的所有路径用绿色标出,可以看到有三条路径可以转移到 b[8] ,也就是说,b[8] 最终的值加了三次 a[3]。其他点也是如此,比如 b[8] 加了一次 a[8],加了两次 a[7]

路径数量就是 a 对 b 贡献的倍率,可以用组合数来求,纵向有 K 条线,横向有 log 条线。虽然 K 很大,但是从组合数公式入手,分子分母分别只有 log 项,暴力计算即可,复杂度 nlogn。

已知 a 计算 b 容易,反过来也不难。只需要让 bi 减去 a1...ai1 对它的贡献,得出 aibi 的贡献,这个贡献只有一次,就是 ai 本身。

#include <bits/stdc++.h> #define FOR() ll le=e[u].size();for(ll i=0;i<le;i++) #define QWQ cout<<"QwQ\n"; #define ll long long using namespace std; const ll N=501010; const ll qwq=303030; const ll inf=0x3f3f3f3f; const ll p=998244353; inline ll read() { ll sum = 0, ff = 1; char c = getchar(); while(c<'0' || c>'9') { if(c=='-') ff = -1; c = getchar(); } while(c>='0'&&c<='9') { sum = sum * 10 + c - '0'; c = getchar(); } return sum * ff; } ll T; ll n,K; ll f[N],a[N],ni[N]; inline ll ksm(ll aa,ll bb) { ll sum = 1; while(bb) { if(bb&1) sum = sum * aa %p; bb >>= 1; aa = aa * aa %p; } return sum; } inline ll C(ll A,ll B) { ll res = ni[B]; for(ll i=1;i<=B;i++) (res *= (A-i+1)%p) %= p; return res; } void qiu(ll h) { f[0] = ni[0] = 1; for(ll i=1;i<=h;i++) f[i] = f[i-1] * i %p; ni[h] = ksm(f[h], p-2); for(ll i=h-1;i;i--) ni[i] = ni[i+1] * (i+1) %p; } int main() { qiu(123); T = read(); while(T--) { n = read(); K = read(); for(ll i=1;i<=n;i++) a[i] = read(); for(ll i=1;i<=n;i++) { ll ju = 2; ll j = i+(i&-i); for(;j<=n;j+=(j&-j),ju++) { (a[j] -= a[i] * C(K+ju-2, ju-1) %p) %= p; } } for(int i=1;i<=n;i++) cout<<(a[i]%p+p)%p<<" \n"[i==n]; } return 0; }

__EOF__

本文作者枫叶晴
本文链接https://www.cnblogs.com/maple276/p/18187128.html
关于博主:菜菜菜
版权声明:呃呃呃
声援博主:呐呐呐
posted @   maple276  阅读(34)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
点击右上角即可分享
微信分享提示