本地搬运~
关于树状数组的学习,强烈推荐这个视频:https://www.bilibili.com/video/av26371798?from=search&seid=2141442207537065040
1:树状数组:查询和修改复杂度都为log(n)的数据结构,本身可用于单点修改区间查询,加入辅助数组后可实现区间修改:POJ3468
2:参考视频,我整理了这张图:
单点更新:
cin>>x;
update(i,x);
void update(int id,int x)
{
for(int i=id;i<=n;i+=lowbit(i))
c[i]+=x;
}
查询[L,R]的区间和
cin>>i>>j;
cout<<getsum(j)-getsum(i-1)<<endl;
int getsum(int id)
{
int sum=0;
for(int i=id;i>=1;i-=lowbit(i))
sum+=c[i];
return sum;
}
lowbit求的是C[i]的i变为二进制后,从右往左找到第一个1的出现位置,固定这个1,其他全为0,再化为十进制。
int lowbit(int i)
{
return i&(-i);
}
HDU1166:基本板子题:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=5e4+10;
int c[maxn],n;
int lowbit(int i)
{
return i&(-i);
}
void update(int id,int x)
{
for(int i=id;i<=n;i+=lowbit(i))
c[i]+=x;
}
int getsum(int id)
{
int sum=0;
for(int i=id;i>=1;i-=lowbit(i))
sum+=c[i];
return sum;
}
int main()
{
int t;
cin>>t;
int ac=1;
while(t--)
{
printf("Case %d:\n",ac++);
cin>>n;
int x;
memset(c,0,sizeof(c));
for(int i=1;i<=n;i++)
{
cin>>x;
update(i,x);
}
string ch;
while(cin>>ch)
{
if(ch=="End")
{
break;
}
if(ch=="Add")
{
int i,j;
cin>>i>>j;
update(i,j);
}
if(ch=="Sub")
{
int i,j;
cin>>i>>j;
update(i,-j);
}
if(ch=="Query")
{
int i,j;
cin>>i>>j;
cout<<getsum(j)-getsum(i-1)<<endl;
}
}
}
}