T3 魔法少女(kisara)
我们先初步化简一下原式,即:
ans=r∑l′=lr∑r′=l′(r′∑i=l′ai)2+r∑l′=lr∑r′=l′(r−l+2)(r′−l′)al′ar′
将式子中后面那一堆中的 r−l+2 提出来,即:
ans=r∑l′=lr∑r′=l′(r′∑i=l′ai)2+(r−l+2)r∑l′=lr∑r′=l′(r′−l′)al′ar′
我们单独分析一下 ans 前面那一堆,将平方拆开,会变成:
ans2=r∑l′=lr∑r′=l′(r′∑l′ai)2=r∑l′=lr∑r′=l′(r′∑l′a2i+2×∑l′≤i<r≤r′aiaj)
想象一下最后去掉前两个 ∑ 后合并同类项,那么
对于 a2i 的系数:(i−l+1)×(r−i+1)
对于 aiaj(i<j) 的系数:2×(i−l+1)×(r−j+1)
那么我们就可以重写一下 ans2,即:
ans2=r∑i=l(i−l+1)(r−i+1)a2i+∑l≤i<j≤r2(i−l+1)(r−j+1)aiaj
观察 ans2,我们发现现在的时间复杂度瓶颈还是在于后面那一堆,那我们接下来再来单独分析一下 ans2 后面那一堆。
我们想要让后面的那一堆达到类似于 (r∑i=lxiai)×(r∑i=lyiai) 的效果。
由于后面那一堆的式子的系数为 2,所以我们可以尝试把它写开:
ans3=∑l≤i<j≤r(i−l+1)(r−j+1)aiaj+∑l≤i<j≤r(i−l+1)(r−j+1)aiaj
发现我们现在只有 i<j 的情况,没有 j<i 的情况,我们可以先暂时将后面那一堆的 i 和 j 两个变量交换一下:
ans3=∑l≤i<j≤r(i−l+1)(r−j+1)aiaj+∑l≤j<i≤r(j−l+1)(r−i+1)aiaj
很显然,我们发现,虽然有了 i<j 和 j<i 的情况,但是前面的系数对不上,所以我们可以将后面那个式子转化一下:
ans3=∑l≤i<j≤r(i−l+1)(r−j+1)aiaj+∑l≤j<i≤r[i−l+1−(i−j)][r−j+1−(i−j)]aiaj
设 ans4 为后面那一堆,把后面的化开:
ans4=∑l≤j<i≤r(i−l+1)(r−j+1)aiaj+∑l≤j<i≤r(i−j)2aiaj−∑l≤j<i≤r(i−j)(r−l+i−j+2)aiaj
第一项不就是我们想要的东西吗?
我们发现,ans4 的最后一项看起来非常的恶心,但是我们发现第二项的系数里有 i−j 和前面的 i−j 共同组成一个 (i−j)2,还有 r−l+2 与前面的 i−j 共同组成一个 (r−l+2)(i−j),即:
ans5=∑l≤j<i≤r(i−j)2aiaj+∑l≤j<i≤r(r−l+2)(i−j)aiaj
那么 ans5 的第一项和 ans4 的第二项就可以消掉了。
将 ans5 代进 ans4 为:
ans4=∑l≤j<i≤r(i−l+1)(r−j+1)aiaj−∑l≤j<i≤r(r−l+2)(i−j)aiaj
非常简洁!
继续带回 ans3,即:
ans3=∑l≤i<j≤r(i−l+1)(r−j+1)aiaj+∑l≤j<i≤r(i−l+1)(r−j+1)aiaj−∑l≤j<i≤r(r−l+2)(i−j)aiaj
我们发现,前面那两项合并之后就是 r∑i=lr∑j=l(i−l+1)(r−j+1)aiaj−r∑i=l(i−l+1)(r−i+1)a2i
相当于就是缺少了 i=j 的情况,只需要抠掉就是上面的式子了。
继续带回 ans3,即:
ans3=r∑i=lr∑j=l(i−l+1)(r−j+1)aiaj−r∑i=l(i−l+1)(r−i+1)a2i−∑l≤j<i≤r(r−l+2)(i−j)aiaj
再带回 ans2,即:
ans2=r∑i=lr∑j=l(i−l+1)(r−j+1)aiaj−r∑i=l(i−l+1)(r−i+1)a2i−∑l≤j<i≤r(r−l+2)(i−j)aiaj+r∑i=l(i−l+1)(r−i+1)a2i
第二项和第四项又可以消掉哩!ans2 就变成了:
ans2=r∑i=lr∑j=l(i−l+1)(r−j+1)aiaj−∑l≤j<i≤r(r−l+2)(i−j)aiaj
最后再带回 ans 就是:
ans=r∑i=lr∑j=l(i−l+1)(r−j+1)aiaj−∑l≤j<i≤r(r−l+2)(i−j)aiaj+(r−l+2)r∑l′=lr∑r′=l′(r′−l′)al′ar′
重写一下 ans 的第二项和第三项:
ans=r∑i=lr∑j=l(i−l+1)(r−j+1)aiaj−(r−l+2)∑l≤j<i≤r(i−j)aiaj+(r−l+2)∑l≤i≤j≤r(j−i)aiaj
第二项中,发现当 i=j 时,i−j 直接等于 0 了,对答案没有影响,我们可以直接将 i=j 的情况放进去:
ans=r∑i=lr∑j=l(i−l+1)(r−j+1)aiaj−(r−l+2)∑l≤j≤i≤r(i−j)aiaj+(r−l+2)∑l≤i≤j≤r(j−i)aiaj
交换第二项的 i 和 j 得:
ans=r∑i=lr∑j=l(i−l+1)(r−j+1)aiaj−(r−l+2)∑l≤i≤j≤r(j−i)aiaj+(r−l+2)∑l≤i≤j≤r(j−i)aiaj
然后第二项和第三项就又可以消掉啦!
最后 ans 就是 r∑i=lr∑j=l(i−l+1)(r−j+1)aiaj
重写一下 ans 就是:
ans=[r∑i=l(i−l+1)ai][r∑j=l(r−j+1)aj]
只需要线段树维护 i×ai 之和和 ai 之和即可,此步骤支持区间修改和区间求和。
时间复杂度 O(qlogn)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现