CODE[VS] 1080 : 点击进入魔塔第一层
CODE[VS] 1081 : 点击进入魔塔第二层
树状数组是个好东西,常数比线段树小,代码比线段树简单
基于区间加法,资磁区间求和,区间修改,单点查询,单点修改,区间查询………
关于lowbit数组,这是一个非常神奇的东西,很难想象第一个想到这样来给数组划分的人时怎么想到的
lowbit[i]存的是某一个数,取其二进制最一个1所在位置的数,显然奇数lowbit == 1
每次修改区间沿着lowbit方向,每次查询逆lowbit方向
更详细的说明可以参见刘汝佳的《算法竞赛入门经典》一书或其他神犇的Blog
线段树练习(区间求和,单点修改)
#include <cstdio>
#include <iostream>
using namespace std;
int n,m;
int a[100001];
int lowbit(int x)
{
return x&(-x);
}
void update(int x,int num)
{
while(x<=n)
{
a[x]+=num;
x+=lowbit(x);
}
}
int sum(int x)
{
int sum=0;
while(x>0)
{
sum+=a[x];
x-=lowbit(x);
}
return sum;
}
int main()
{
int i,j,temp;
int a,x,y;
scanf("%d",&n);
for(i=1;i<=n;i++)
{
scanf("%d",&temp);
update(i,temp);
}
scanf("%d",&m);
for(i=1;i<=m;i++)
{
scanf("%d%d%d",&a,&x,&y);
if(a==1) update(x,y);
else printf("%d\n",sum(y)-sum(x-1));
}
return 0;
}
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cstdlib>
const int maxn = 100005;
using namespace std;
int n,q;
int c[maxn];
int b[maxn];
int lowbit(int x)
{
return x&(-x);
}
inline void add(int i,int num)
{
while(i <= n)
{
c[i] += num;
i += lowbit(i);
}
}
inline int sum(int x)
{
int tot = 0;
while(x > 0)
{
tot += c[x];
x -= lowbit(x);
}
return tot;
}
int main()
{
scanf("%d",&n);
for(int i =1;i <=n;i++)
{
int x;
scanf("%d",&x);
add(i,x);
}
scanf("%d",&q);
for(int i = 1;i <= q;i++)
{
int cz;
int aa,bb,xx,ii;
scanf("%d",&cz);
if(cz == 1)
{
scanf("%d%d%d",&aa,&bb,&xx);
for(int j = aa;j <= bb;j++)
{
add(j,xx);
}
}
if(cz == 2)
{
scanf("%d",&ii);
printf("%d\n",sum(ii)-sum(ii-1));
}
}
return 0;
}
THE END
By Peacefuldoge