UVA 1428 - Ping pong 二叉索引树标准用法
分析:
感觉白书写的不太好理解,说下自己稍微改动后的分析。
想象一条数轴,数轴上的点表示能力值。
用数组c[i]表示在二叉索引树中以a[i]结尾的“水平长条”。
所以每输入一个能力值都要更新与之相关的c[i]的值。
第i个人当裁判时,
计算到目前为止(即a[1]到a[i-1])数轴上a[i]左边的标记的个数,即前缀和,存入front[i],则a[i]右边就有i-1-front[i]个。
重新逆序计算到目前为止(即a[n]到a[i+1])数轴上a[i]左边的标记的个数,即前缀和,存入back[i],则a[i]右边就有n-i-back[i]。
说的很乱。。意会就好了。。这是我的代码:
#include <stdio.h> #include <string.h> int t, n, a[20010], c[100010], front[20010], back[20010]; int lowbit(int x) { return x & -x; } int sum(int x) { int ans = 0; while(x > 0) { ans += c[x]; x -= lowbit(x); } return ans; } void add(int x, int d) { while(x <= 100000) { c[x] += d; x += lowbit(x); } } int main() { scanf("%d", &t); while(t--) { scanf("%d", &n); memset(c, 0, sizeof(c)); for(int i = 1; i <= n; i++) { scanf("%d", &a[i]); add(a[i], 1); front[i] = sum(a[i]-1); } memset(c, 0, sizeof(c)); for(int i = n; i >= 1; i--) { add(a[i], 1); back[i] = sum(a[i]-1); } long long ans = 0; for(int i = 2; i < n; i++) ans += 1LL * front[i]*(n-i-back[i]) + (i-front[i]-1)*back[i]; printf("%lld\n", ans); } return 0; }
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· PostgreSQL 和 SQL Server 在统计信息维护中的关键差异
· C++代码改造为UTF-8编码问题的总结
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· 【.NET】调用本地 Deepseek 模型
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库
· 上周热点回顾(2.17-2.23)
· 如何使用 Uni-app 实现视频聊天(源码,支持安卓、iOS)