Fenwick 树状数组上二分
其实应该叫倍增。
由于这篇文章中 估计不少,所以一律用 。
Acwing244. 谜一样的牛
给定一个长度 序列,求逆康托。
若是 二分,再 Fenwick, 要跑 600ms,数据加强一下就过不了。
若是 在线段树上二分,常数过大。
所以我们就请出了主题——树状数组上二分
原理是位置 存的是以 为右端点长度为 区间信息。
由于 都是 的幂,所以就是倍增的料!
不管了,好像代码更能让你懂。
/* * Author: ShaoJia * Last Modified time: 2022-09-26 19:47:51 * Motto: We'll be counting stars. */ #pragma GCC optimize("Ofast") #include<bits/stdc++.h> using namespace std; #define For(i,j,k) for(int i=(j),i##_=(k);i<=i##_;i++) #define Rof(i,j,k) for(int i=(j),i##_=(k);i>=i##_;i--) const int N=1e5+5; int n,a[N],c[N],b[N]; inline int low(int x){ return x&(-x); } void add(int x,int y){ while(x<=n) c[x]+=y,x+=low(x); } int jump(int x){//the last pos that presum<=x int pos=0,sum=0,np; Rof(i,20,0) if((np=pos|(1<<i))<=n && sum+c[np]<=x) sum+=c[np],pos=np; return pos; } signed main(){ios::sync_with_stdio(false),cin.tie(nullptr); cin>>n; For(i,2,n) cin>>a[i]; For(i,1,n) c[i]=low(i); Rof(i,n,1) b[i]=jump(a[i])+1,add(b[i],-1); For(i,1,n) cout<<b[i]<<"\n"; return 0;}
P6619 [省选联考 2020 A/B 卷] 冰火战士
代码和题解都贺。
本文来自博客园,作者:ShaoJia,版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义