首页 > 其他分享 >Fenwick 树状数组上二分

Fenwick 树状数组上二分

时间:2022-09-26 20:04:28浏览次数:49  
标签:二分 log 树状 int Fenwick low

其实应该叫倍增。

由于这篇文章中 \(\text{lowbit}\)

Acwing244. 谜一样的牛

给定一个长度 \(n\le 10^5\) 序列,求逆康托。

\(0\le a_i<i\)

若是 \(\log n\) 二分,再 \(\log n\) Fenwick,\(O(n\log^2 n)\) 要跑 600ms,数据加强一下就过不了。

若是 \(\log n\) 在线段树上二分,常数过大。

所以我们就请出了主题——树状数组上二分

原理是位置 \(x\) 存的是以 \(x\) 为右端点长度为 \(\text{low}\)

/*
* 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;}

标签:二分,log,树状,int,Fenwick,low
From: https://www.cnblogs.com/shaojia/p/16732155.html

相关文章

  • 2021杭电多校1 J (普通莫队 树状数组)
    题意:给出1e5个二维平面上的坐标点0<=(x,y)<=1e5,1e5个询问,每次问x0,y0到x1,y1的矩阵中有多少y值不同的坐标点。思路:操作只有询问,不强制在线,数据范围1e5,就差把莫......
  • mex(权值线段树+线段树上二分)
      思路:首先看到区间维护,想到线段树,但是很明显无法用线段树直接维护区间最小没出现过的自然数,因为假若一个节点的左右儿子节点的值都为0,我们是无法推断出父节点的值是几......
  • 树状数组和线段树资料
    例题和代码模板:https://www.cnblogs.com/pavtlly/p/9979702.html看老师这个博客链接吧 https://zhuanlan.zhihu.com/p/106118909线段树资料 线段树进阶资料(有兴......
  • 二分查找算法
    简介只能对有序数组进行查找代码实现publicclassBinarySearch{ publicstaticvoidmain(String[]args){ //查找单个数据 intarr[]={1,8,10,8......
  • 二分查找模板
    //arr数组升序//n是数组长度,也就是lr正好是数组的左右的第一个和最后一个intl=0,r=n-1;intmid;while(l<=r){mid=(l+r)/2;if(arr[mid]==......
  • 二分查找步骤及问题总结
    二分查找参数:有序数组arr(这里按升序来讲),待搜索的值target步骤定义左边界left和有边界right获取中间索引(整数)mid=(left+right)/2,注意:js只有小数,mid需要再取整......
  • 二分模板
    intsearch(vector<int>&nums,inttarget){intleft=0,right=nums.size();intmid;while(left<right){mid=(left+right)>>1;......
  • 实例84 二分法求解方程
    #include<stdio.h>#include<math.h>#include<malloc.h>#include<stdlib.h>doubleFunc(double);intBisectRoot(double,double,double,double,double*,int,in......
  • 代码随想录 数组理论基础,二分查找,移除元素 及 LeetCode 704, 27
    数组理论基础数组是存放在连续内存空间上的相同类型数据的集合。数组下标都是从0开始的。数组内存空间的地址是连续的因为数组的在内存空间的地址是连续的,所以我们在......
  • 代码随想录训练营|Day 1|数组理论基础,704. 二分查找,27. 移除元素
    数组理论基础数组是存放在连续内存空间上的相同类型数据的集合。startwithindex0数组内存空间的地址是连续的数组的元素是不能删的,只能覆盖。二维数组:BinaryS......