树状数组。。

来源:互联网 发布:网络视频下载器 编辑:程序博客网 时间:2024/06/06 04:04

一维树状数组

hdu 1166

#include <iostream>#include <cstring>#include <cmath>#include <cstdlib>#include <cstdio>#include <algorithm>#include <queue>#include <stack>#define LL long long#define MAX 0x3f3f3f3f#define N (50000 + 5)using namespace std;int a[N], n;int lowbit(int x){    return x & (-x);}void add(int pi, int val){    while (pi <= n)    {        a[pi] += val;        pi += lowbit(pi);     //向上取整    }}int sum(int pi){    int ans = 0;    while (pi > 0)    {        ans += a[pi];        pi -= lowbit(pi);     }    return ans;}int main(){    int T;    scanf("%d", &T);    for (int cas = 1; cas <= T; cas++)    {        scanf("%d", &n);        printf("Case %d:\n", cas);        memset(a, 0, sizeof(a));        for (int i = 1; i <= n; i++)        {            int t;            scanf("%d", &t);            add(i, t);        }        while(1)        {            char s1[10];            scanf("%s", s1);            if(s1[0] == 'Q')            {                int s, t;                scanf("%d%d", &s, &t);                printf("%d\n", sum(t) - sum(s - 1));            }            else if(s1[0] == 'A')            {                int pi, val;                scanf("%d%d", &pi, &val);                add(pi, val);            }            else if(s1[0] == 'S')            {                int pi, val;                scanf("%d%d", &pi, &val);                add(pi, -val);            }            else            {                break;            }        }    }}

hdu 3972
题目大意:求0~n范围内两个相邻素数(差为2)的个数。
素数打表。。情况成立。。标记在第二个数上。。。

#include <iostream>#include <cstring>#include <cmath>#include <cstdlib>#include <cstdio>#include <algorithm>#include <queue>#include <stack>#include <string>#define LL long long#define MAX 0x3f3f3f3f#define N 100005#define M 32010using namespace std;bool  not_prim[N];int d[N];int lowbit(int x){    return x & (-x);}void add(int pi){    while (pi < N)    {        d[pi] += 1;        pi += lowbit(pi);    }}int sum(int pi){    int ans = 0;    while (pi > 0)    {        ans += d[pi];        pi -= lowbit(pi);    }    return ans;}void is_prime(){    memset(not_prim, 0, sizeof(not_prim));    for (int i = 2; i * i <= N; i++)    {        if (!not_prim[i])        {            for (int j = i * i; j <= N; j += i)            {                not_prim[j] = 1;            }        }    }    for (int i = 5; i <= N; i += 2)    {        if (not_prim[i] == 0 && not_prim[i - 2] == 0)        {            // cout << 'i' << ' ' << i << endl;            add(i);        }    }}int main(){    int n;    memset(d, 0, sizeof(d));    is_prime();    while (~scanf("%d", &n) && n >= 0)    {        printf("%d\n", sum(n));    }}

hdu 1541
题目大意:求某星星左下方的个数。。(纵坐标按升序排列)

#include <iostream>#include <cstring>#include <cmath>#include <cstdlib>#include <cstdio>#include <algorithm>#include <queue>#include <stack>#include <string>#define LL long long#define MAX 0x3f3f3f3f#define N 15005#define M 32010using namespace std;int n, d[M], level[M];int lowbit(int x){    return x & (-x);}void add(int pi){    while (pi <= M)    {        d[pi] += 1;        pi += lowbit(pi);    }}int sum(int pi){    int ans = 0;    while (pi > 0)    {        ans += d[pi];        pi -= lowbit(pi);    }    return ans;}int main(){    while (~scanf("%d", &n))    {        int x, y;        memset(d, 0, sizeof(d));        memset(level, 0, sizeof(level));        for (int i = 1; i <= n; i++)        {            scanf("%d%d", &x, &y);            level[sum(++x)]++;            add(x);        }        for (int i = 0; i < n; i++)        {            printf("%d\n", level[i]);        }    }}

hdu 2689
题目大意:将数据排列成升序。。求最少的排列次数。。(求逆序数)
全赋为0,输一个数则在该位置标记为1,统计比他小的输的个数

#include <iostream>#include <cstring>#include <cmath>#include <cstdlib>#include <cstdio>#include <algorithm>#include <queue>#include <stack>#include <string>#define LL  __int64#define MAX 0x3f3f3f3f#define N 1005using namespace std;int n;int d[N];int lowbit(int x){    return x & (-x);}void add(int pi, int num){    while(pi <= n)    {        d[pi] += 1;        pi += lowbit(pi);    }}LL sum(int pi){    LL sum = 0;    while(pi > 0)    {        sum += d[pi];        pi -= lowbit(pi);    }    return sum;}int main(){    while (~scanf("%d", &n))    {        int t;        memset(d, 0, sizeof(d));        int cnt = 0;        for (int i = 1; i <= n; i++)        {            scanf("%d", &t);            add(t, 1);            cnt += i - sum(t);        }        cout << cnt << endl;    }}

hdu 2838
题目大意:在2689的基础上求交换的最小代价;
开两个树状数组,分别记录其个数和代价。。。

#include <iostream>#include <cstring>#include <cmath>#include <cstdlib>#include <cstdio>#include <algorithm>#include <queue>#include <stack>#include <string>#define LL  __int64#define MAX 0x3f3f3f3f#define N 100005using namespace std;int n;struct node{    int num;    LL sum;}d[N];int lowbit(int x){    return x & (-x);}void add(int pi, int num){    while(pi <= 100000)    {        d[pi].num += 1;        d[pi].sum += num;        pi += lowbit(pi);    }}int get_num(int pi)//得到比当前数小的数的个数{    int num = 0;    while(pi > 0)    {        num += d[pi].num;        pi -= lowbit(pi);    }    return num;}LL get_sum(int pi)//得到比当前数小的数的和{    LL sum = 0;    while(pi > 0)    {        sum += d[pi].sum;        pi -= lowbit(pi);    }    return sum;}int main(){    while(~scanf("%d", &n))    {        memset(d, 0, sizeof(d));        int num;        LL ans = 0;        for(int i = 1; i <= n; i++)        {            scanf("%d", &num);            add(num, num);            int cnt = i - get_num(num);//有cnt的数比num大            if(cnt != 0)            {                ans += (LL)cnt * num + get_sum(100000) - get_sum(num);            }        }        printf("%I64d\n", ans);    }    return 0;}

hdu 4046
hdu 2433
hdu 4312

二维树状数组

hdu 1559
求子矩阵的和最大

#include <iostream>#include <cstring>#include <cmath>#include <cstdlib>#include <cstdio>#include <algorithm>#include <queue>#include <stack>#include <string>#define LL  __int64#define MAX 0x3f3f3f3f#define N 1005using namespace std;int n, m;int d[N][N];int lowbit(int x){    return x & (-x);}void add(int pi, int pj, int val){    for (int i = pi; i <= n; i += lowbit(i))    {        for (int j = pj; j <= m; j += lowbit(j))        {            d[i][j] += val;        }    }}int sum(int pi, int pj){    int ans = 0;    for (int i = pi; i > 0; i -= lowbit(i))    {        for (int j = pj; j > 0; j -= lowbit(j))        {            ans += d[i][j];        }    }    return ans;}void init(){    for (int i = 0; i <= n; i++)    {        for (int j = 0; j <= m; j++)        {            d[i][j] = 0;        }    }}int main(){    int T;    scanf("%d", &T);    // memset(d, 0, sizeof(d));    while (T--)    {        int x, y, t;        scanf("%d%d%d%d", &n, &m, &x, &y);        init();        for (int i = 1; i <= n; i++)        {            for (int j = 1; j <= m; j++)            {                scanf("%d", &t);                add(i, j, t);            }        }        int temp, Max = 0;        for (int i = 1; i + x - 1 <= n; i++)        {            for (int j = 1; j + y - 1 <= m; j++)            {                temp = sum(i + x - 1, j + y - 1) - sum(i - 1, j + y - 1) - sum(i + x - 1, j - 1) + sum(i - 1, j - 1);                Max = max(Max, temp);            }        }        printf("%d\n", Max);    }}

hdu 1892
hdu 2852
hdu 2642
hdu 4311
hdu 2836

0 0
原创粉丝点击