树状数组

#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;
}