1)lowbit(x)=x & (-x)
将x转换为二进制,则lowbit(x)就是右边第一个'1'号位表示的位权
lowbit 可以理解为能整除x的最大的2的幂次
///c[x]存储a[x](含x号位)前Lowbit(x)个数
///c[x]=a[x-lowbit(x)+1]+...+a[x];
///-> sum(1,x)=a[1]+a[2]+...+a[x]=
/// a[1]+...+a[x-lowbit(x)]+a[x-lowbit[x]+1]+...+a[x]
/// =a[1]+...+a[x-lowbit[x]]+c[x];
///-> sum(1,x)=sum(1,x-lowbit(x))+c[x];
/**
1)lowbit(x)=x & (-x)
将x转换为二进制,则lowbit(x)就是右边第一个'1'号位表示的位权
lowbit 可以理解为能整除x的最大的2的幂次
*/
/**
#include <iostream>
using namespace std;
void update(int x,int v);
int getsum(int x);
#define lowbit(x) ((x)&(-x))
const int maxn=1001;
int c[maxn];
int main()
{
memset(c,0,sizeof(c));
int n,x;
cin >> n;
for(int i=0;i<n;++i)
{
cin >> x;
update(x,1);
cout << "append " << getsum(x-1) << endl; //a[i]左边比a[i]小的元素个数
cout << "append " << getsum(maxn)-getsum(x) << endl; //a[i]左边比a[i]大的元素个数
}
///以下的代码是求a[i]右边比它小或大的个数
cin >> n;
int a[n];
for(int i=0;i<n;++i)
cin >> a[i];
for(int i=n-1;i>=0;--i)
{
update(a[i],1);
cout << "append " << getsum(a[i]-1) << endl; //a[i]右边比a[i]小的元素个数
cout << "append " << getsum(maxn)-getsum(a[i]) << endl; //a[i]右边比a[i]大的元素个数
}
return 0;
}
///c[x]存储a[x](含x号位)前Lowbit(x)个数
///c[x]=a[x-lowbit(x)+1]+...+a[x];
///-> sum(1,x)=a[1]+a[2]+...+a[x]=
/// a[1]+...+a[x-lowbit(x)]+a[x-lowbit[x]+1]+...+a[x]
/// =a[1]+...+a[x-lowbit[x]]+c[x];
///-> sum(1,x)=sum(1,x-lowbit(x))+c[x];
int getsum(int x)
{
int sum=0;
while(x>0)
{
sum+=c[x];
x-=lowbit(x);
}
return sum;
}
void update(int x,int v)
{
for(int i=x;i<maxn;i+=lowbit(i))
c[i]+=v;
}
*/
2) 当a[i]太大以至于开不了这么大的数组的是时候,可以将值存到
结构体中,将他们的大小序号与结构体数组下标对应起来
lowbit(x)=x&(-x)
将x转换为二进制,则lowbit(x)就是右边第一个'1'号位表示的位权
lowbit 可以理解为能整除x的最大的2的幂次
单点更新,区间查询
/**
2) 当a[i]太大以至于开不了这么大的数组的是时候,可以将值存到
结构体中,将他们的大小序号与结构体数组下标对应起来
lowbit(x)=x&(-x)
将x转换为二进制,则lowbit(x)就是右边第一个'1'号位表示的位权
lowbit 可以理解为能整除x的最大的2的幂次
单点更新,区间查询
*/
/**
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
void update(int x,int v);
int getsum(int x);
int find_kth_element(int k);//寻找序列中第k大的数
#define lowbit(x) ((x)&(-x))
const int maxn=1001;
struct Node
{
int val;
int pos;
};
bool cmp(Node a,Node b)
{
return a.val<b.val;
}
int c[maxn];
int main()
{
memset(c,0,sizeof(c));
int n;
cin >> n;
Node temp[n];
int a[n];
for(int i=0;i<n;++i)
{
cin >> temp[i].val;
temp[i].pos=i;
}
sort(temp,temp+n,cmp);
for(int i=0;i<n;++i)
{
if(i==0||temp[i].val!=temp[i-1].val)
a[temp[i].pos]=i+1; //第一个数必须从1开始存储,因为在调用update函数时,会进行loebit操作
else //而lowbit(0)是等于0,就会进入死循环
a[temp[i].pos]=a[temp[i-1].pos];
}
for(int i=0;i<n;++i) //必须先将元素存到数组c中,才能查询序列的排名
update(a[i],1); //因为查询排名也是要调用getsum,而getsum函数也是需要数组c的
cout << find_kth_element(n-2) << endl;
cout << temp[find_kth_element(n-2)-1].val << endl;
return 0;
}
//c[x]存储a[x](含x号位)前Lowbit(x)个数
//c[x]=a[x-lowbit(x)+1]+...+a[x];
//-> sum(1,x)=a[1]+a[2]+...+a[x]=
// a[1]+...+a[x-lowbit(x)]+a[x-lowbit[x]+1]+...+a[x]
// =a[1]+...+a[x-lowbit[x]]+c[x];
//-> sum(1,x)=sum(1,x-lowbit(x))+c[x];
int getsum(int x) //返回前x个数的和
{
int sum=0;
while(x>0)
{
sum+=c[x];
x-=lowbit(x);
}
return sum;
}
void update(int x,int v) //第x个数加上v
{
for(int i=x;i<maxn;i+=lowbit(i))
{
c[i]+=v;
}
}
int find_kth_element(int k)
{
int mid,l=1,r=maxn;
while(l<r)
{
mid=(l+r)/2;
if(getsum(mid)>=k)
r=mid;
else
l=mid+1;
}
return l;
}
*/
3) lowbit(x)=x&(-x)
将x转换为二进制,则lowbit(x)就是右边第一个'1'号位表示的位权
lowbit 可以理解为能整除x的最大的2的幂次
单点更新,区间查询
返回二维矩阵a[1][1]到a[i][j](一个子矩阵)的和
/**
3) lowbit(x)=x&(-x)
将x转换为二进制,则lowbit(x)就是右边第一个'1'号位表示的位权
lowbit 可以理解为能整除x的最大的2的幂次
单点更新,区间查询
返回二维矩阵a[1][1]到a[i][j](一个子矩阵)的和
*/
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
void update(int x,int y,int v);
int getsum(int x,int y); //返回二维矩阵a[1][1]到a[i][j]的和
#define lowbit(x) ((x)&(-x))
const int maxn=1001;
int c[maxn][maxn];
int main()
{
memset(c,0,sizeof(c));
int m,n;
cin >> m >> n;
cout << "输入 " << m << "行" << n << "列的矩阵\n";
int a[m][n];
for(int i=1;i<=m;++i)
for(int j=1;j<=n;++j)
{
cin >> a[i][j];
update(i,j,a[i][j]);
}
cout << getsum(m-1,n-1) << endl;
return 0;
}
int getsum(int x,int y) //返回二维矩阵a[1][1]到a[i][j]的和
{
int sum=0;
for(int i=x;i>0;i-=lowbit(i))
for(int j=y;j>0;j-=lowbit(j))
sum+=c[i][j];
return sum;
}
void update(int x,int y,int v) //包含a[i][j]的矩阵,数组c都加上v
{
for(int i=x;i<maxn;i+=lowbit(i))
for(int j=y;j<maxn;j+=lowbit(j))
c[i][j]+=v;
}