树状数组
树状数组
可以利用多个树状数组来实现数组的区间更新,参考:A Simple Problem with Integers
#define ll long long
#define lowbit(i) (i&-i)
const int maxn=1e5+5;
int c[maxn], w[maxn], laz[maxn << 2];
ll n,mod=1e9+7;
/*单点更新*/
void add(int x, int k)
{
while (x<=n)
c[x]=(c[x]+k)%mod, x+=lowbit(x);
}
/*求w[1]~w[x]的和*/
ll getSum(int x)
{
ll ans=0;
while (x>0)
ans=(ans+c[x])%mod, x-=lowbit(x);
return ans%mod;
}
/*求w[l]~w[r]的和*/
ll getsum(int l, int r, int s, int t, int p)
{
return (getSum(r)-getSum(l-1)+mod)%mod;
}
/*初始化*/
void init()
{
for(int i=1;i<=n;++i)
add(i,w[i]);
}
一些关于树状数组的技巧
/*O(n)建树*/
void init()
{
for(int i=1;i<=n;++i)
{
c[i]+=w[i];
int j=i+lowbit(i);
if(j<=n) c[j]+=c[i];
}
}
/*O(log n)查询第k小*/
int k_th(int k)
{
int cnt=0,ret=0;
for(int i=log2(n);~i;--i)
{
ret+=1<<i;
if(ret>=n||cnt+c[ret]>=k)
ret-=1<<i;
else cnt+=c[ret];
}
return ret+1;
}
CAD加油!欢迎跟我一起讨论学习算法,QQ:1401650042