暂时不熟悉的用法
宏定义:
define L(x) (x«1)//将x乘以2
define R(x) (x«1|1)//将x乘以2加1,注意后面|1就是加1,其他的不一定正确
线段树的深度为log2(b-a+1)
线段数组基本知识:
1.通常我们用lowbit(x)表示x对应的2^k;
2.lowbit(x)=x&(-x);
3.lowbit(x)实际上就是x的二进制表示形式留下最右边的1,其他位都变成0
数组a对应的线段数组应该是C[i]=a[i-lowbit(i)+1]+…+a[i]
hdu 1166我居然挂了20多次
hdu 1166
虽然是一个人的战场,但你永远不会独行!you nerver go alone!
线段树的简单使用可以用以下模板,高级还需自己慢慢领会
- 下面是基于线段树结构的代码
这是树状数组的做法,参考了
树状数组;
#include
#include
using namespace std;
int st[50005];
//2^k==lowbit(x)
int lowbit(int a)
{
return a&(-a);
}
void update(int p,int val,int N)
{
while(p<=N)
{
st[p]+=val;//主要是向后衍生使用的
p+=lowbit(p);
}
}
int getsum(int p)
{
int res=0;
while(p){
res+=st[p];
p-=lowbit(p);
}
return res;
}
void display(int n)
{
for(int i=1;i<=n;i++)
printf(“%d “,st[i]);
}
int main()
{
freopen(“in.txt”,”r”,stdin);
int k,n,x;
int p,q;
char str[5];
scanf(“%d”,&k);
for(int j=1;j<=k;j++){
memset(st,0,sizeof(st));
printf(“Case %d:\n”,j);
scanf(“%d”,&n);
for(int i=1;i<=n;i++)
{
scanf(“%d”,&x);
update(i,x,n);
}
while(scanf("%s",str)&&str[0]!='E'){
scanf("%d%d",&p,&q);
if(str[0]=='A'){
update(p,q,n);
}
if(str[0]=='S'){
update(p,-q,n);
}
if(str[0]=='Q'){
printf("%d\n",getsum(q)-getsum(p-1));
}
}
} }
这里有问题吗?
int lowbit(int a)
{
return a&(-a);
}
一直不理解那个lowbit到底是干什么,上面的文章说可以向后衍生(更新结点)和向前(求和)
向后主要是为了找到目前节点的父节点,比如要将C[4]+1,那么4+(4&(-4))=8,C[8]+1,8+(8&(-8))=16,
C[16]+1。
向前主要是为了求前缀和,比如要求A[1]+…+A[12]。那么,C[12]=A[9]+…+A[12];然后12-12&(-12)=8,
C[8]=A[1]+…+A[8]。
##hdu 1754
hdu 1754
奇了怪了,我的代码与下面的一模一样,我的错,他的对,到底哪里不一样啊
而且还有一件事情,就是在传递参数的时候,t«1放在参数列表的最后一个位置比放置在其他
位置时间更快一些,为什么啊
update()函数中p+=lowbit(p)是推算p在后面的有关的st的位置,至于为什么那真的就是数学证明了
hdu 2795
/*************************
File Name: hdu2795.cpp
Author: damit
Mail: [email protected]
Created Time: 2014年07月21日 星期一 21时15分10秒
学习重点:
原来线段树还可以这样用啊,自己真是长见识了,以后我也要尝试着去写些这类有价值的东西来,
少制造垃圾.
题意:面板是hw,而纸条为1w,从左上角依次填充,若可以则输出最小的行数。利用线段树,右区间为min(n,h),
为什么呢,我们试想想,hw,我们只需h层(最安全),
如35,我们
如果贴2张纸条 ,
则只需建一个【1,2】的线段树,够使用的就可以的。然后每个节点被赋值w(宽度),build(l,r,t)先赋值,判断退 出,然后左右子树分别建立。
查询时,将每个宽度的值传递过来,到叶子节点时去掉宽度值,并返回l,即层数
然后更新父节点,取自左右子树的最大值,以便下次使用。
还有,一开始就判断MAX[1],为什么?
************************/