树状数组

来源:互联网 发布:照明设计软件 编辑:程序博客网 时间:2024/05/09 02:45

树状数组

模板

struct FT{    int na[MAXN+1];    int lowbit(int x){return x&(-x);}    void add(int x,int y){for(;x<=n;x+=lowbit(x)) na[x]+=y;}    int calSum(int x)    {        int res;        for(;x;x-=lowbit(x)) res+=na[x];        return res;     }} ft;

应用

求逆序对

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;typedef long long ll;const int MAXN = 100000;ll n, cnt, a[MAXN + 1], b[MAXN + 1];//b:树状数组,ls:离散后数组ll k;struct mark{    ll n, ln;//数值,原先编号; } ls[MAXN + 1];ll lowbit(ll x){return x & (- x);}void add(ll x, ll y)//x处加上y{    for(; x <= n; x += lowbit(x))     {        b[x] += y;    }}ll sum(ll x){    ll ans = 0;    for(; x; x -= lowbit(x)) ans += b[x];    return ans;}int cmp(const mark & a, const mark & b){return a.n < b.n;}int main(){    int i, j;    ios::sync_with_stdio(false);    while(cin >> n >> k)    {        memset(a, 0, sizeof(a));        memset(b, 0, sizeof(b));        memset(ls, 0, sizeof(ls));        for(i = 1; i <= n; i ++) cin >> a[i], ls[i].n = a[i], ls[i].ln = i;        sort(ls + 1, ls + n + 1, cmp);        cnt = 1;        a[ls[1].ln] = cnt;        for(i = 2; i <= n; i ++)        {            if((ls[i - 1].n != ls[i].n)) cnt ++;            a[ls[i].ln] = cnt;        }        ll ans = 0;        for(i = n; i >= 1; i--)        {            ans += sum(a[i] - 1);            add(a[i], 1);        }        if(ans - k < 0) cout << 0 << endl;         else cout << ans - k << endl;    }    return 0;}

题目:

HDU 4911
HDU 3743
HDU 1394
HDU 5497
NOIP 2012

0 0
原创粉丝点击