数据结构之树状数组

package 树状数组;
//低位操作
//修改操作
//求和
//删除
//插入
//取第K小


public class 模版 {
// 点更新:向上路径更新关键字;
// 区间更新:向下路径更新关键字;
// 更新区间查询点:将inc与get方法互换。
//要注意一个超时陷阱:x==0的情况
static int N;
static int c[]=new int[N];
//要注意一个超时陷阱:x==0的情况

//破解办法有:将要进行统计的数据每一个都加上1,这样就可以避免这种情况

static int lowbit(int i){
int ans=i&(-i);
return ans;
}
//插点问段
static void modify(int k,int d){
while(k<=N){
c[k]+=d;
k+=lowbit(k);
}
}
static int sum(int n){
int result=0;
while(n>0){
result+=c[n];
n-=lowbit(n);
}
return result;
}

//插段问点

static void modify1(int k,int num){
while(k>0){
c[k]+=num;
k-=lowbit(k);
}

}

static int sum1(int n){//用于统计某个点的出现的次数
int s=0;
while(n<=N){
s+=c[n];
n+=lowbit(n);
}
return s;
}

//综上可以看出
//插点问段和插段问点的操作的过程是相反的
//*********************************************

//区间第k小元素,注意值为负数时的需首先离散化
//查询区间不可包含,可以相交,如果包含在处理区间是可能会tle,需谨慎使用此方法。
final int getk(int k) {
int left = 0, right = N, mid, ans = -1;
while (left <= right) {
mid = (left + right) >> 1;
int f = sum(mid);
if (f >= k) {
right = mid - 1;
ans= mid;
} else
left = mid + 1;
}
return ans;
}


}


//***********&&&&&&&&&&&&&&&&&&%%%%%%%%%%%%%%%
int tree[100000];
void iniTree(){memset(tree,0,sizeof(tree));}
inline int Lowbit(int a){return a&-a;}
void ins(int a,int b){//若b==1,插入元素a。若b==-1,删除元素a
     while (a<N){
           tree[a]+=b;
           a+=Lowbit(a+1);
     }
}
int findKth(int k){//寻找第k大的元素
    int i,j;
    i=0;
    while (1){
          j=0;
          while (i<N && tree[i]<k)i+=(j=Lowbit(i+1));
          i-=j;
          k-=tree[i];
          if (!k)break;
          ++i;
          if (Lowbit(i+1)!=1)break;
    }
    return i;
}




//************************




//*******************************************
对于成段更新的理解:
//比如:(a,b)按段更新,即为先将前b段更新,然后将前a-1段消除更新;
//如前b段加1,则前a-1段减1;


题目推荐:
简单:
POJ 2299 Ultra-QuickSort
POJ 2352 Stars
POJ 1195 Mobile phones 
中等
POJ 2155 Matrix 
POJ 3321 Apple Tree
POJ 1990 MooFest 
难题:
 POJ 2464 Brownie Points II 





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值