树状数组合集

来源:互联网 发布:php磁力解析源码 编辑:程序博客网 时间:2024/04/19 03:30

hdu 4605 Magic Ball Game

树状数组在dfs的应用,比较适合求区间的和
#include <cstdio>#include <iostream>#include <algorithm>#include <vector>#include <cstring>using namespace std;#define MAXN 100010/**    从1到v的路径固定,按照dfs的思想,等同于只考虑    一条支路;在一条支路上分为左右部分,找出大于x的    个数和小于x的个数*/int n, m, q;int w[MAXN], cnt, d[MAXN<<1], res[MAXN<<1][2], ans[MAXN][2];struct node {int a, b; node(int _a, int _b):a(_a),b(_b){}};vector<int> son[MAXN];vector<node> mp[MAXN];int lowbit(int c){    return c & -c;}void update(int u, int c, int val){    for (int i = u; i <= cnt; i += lowbit(i))        res[i][c] += val;}int getSum(int u, int c){    int sum = 0;    for (int i = u; i > 0; i -= lowbit(i))        sum += res[i][c];    return sum;}int top, stk[MAXN];int cson[MAXN], mpot[MAXN];void dfs(){    top = 0;    stk[top++] = 1;    memset(cson, 0, sizeof cson);    int u, i, s;    int wei, dx, p, la, ra, lb, rb, lc, rc;    int v, wv;    while (top)    {        u = stk[top-1];        if (cson[u] == 0)        {            s = mp[u].size();            for (i = 0; i< s; ++i)            {                wei = mp[u][i].b;                dx = mp[u][i].a;                p = lower_bound(d, d+cnt, wei)-d+1;                la = getSum(p-1, 0);                ra = getSum(p-1, 1);                lb = getSum(cnt, 0);                rb = getSum(cnt, 1);                lc = lb - getSum(p, 0);                rc = rb - getSum(p, 1);                if (la+ra+lc+rc - lb - rb)                {                    ans[dx][1] = -1;                    continue;                }                ans[dx][0] = ra;                ans[dx][1] = (la+ra)*3 + lc + rc;            }        }        if (son[u].size() == 0)        {            top--;            continue;        }        s = cson[u];        if (s & 0x1)        {            update(mpot[u], s>>1, -1);            s = ++cson[u];            if (s > 3)            {                --top;                continue;            }        }        v = son[u][s>>1];        wv = w[u];        mpot[u] = p = lower_bound(d, d+cnt, wv)-d+1;        update(p, s>>1, 1);        stk[top++] = v;        cson[u]++;    }}int main(){#ifndef ONLINE_JUDGE    freopen("in.txt", "r", stdin);#endif // ONLINE_JUDGE    int t, i;    int u, a, b, x, v;    scanf("%d", &t);    while (t--)    {        scanf("%d", &n);        cnt = 0;        for (i = 0; i<= n; ++i)        {            son[i].clear();        }        for (i = 1; i<= n; ++i)        {            scanf("%d", &w[i]);            d[cnt++] = w[i];        }        scanf("%d", &m);        for (i = 0; i< m; ++i)        {            scanf("%d%d%d", &u, &a, &b);            son[u].push_back(a);            son[u].push_back(b);        }        scanf("%d", &q);        for (i = 0; i<= q; ++i) mp[i].clear();        for (i = 0; i< q; ++i)        {            scanf("%d%d", &v, &x);            mp[v].push_back(node(i, x));            d[cnt++] = x;        }        sort(d, d+cnt);        cnt = unique(d, d+cnt)-d;        memset(res, 0, sizeof res);        dfs();        for (i = 0; i< q; ++i)        {            if (ans[i][1] == -1)                printf("0\n");            else                printf("%d %d\n", ans[i][0], ans[i][1]);        }    }    return 0;}



hdu 4630 No Pain No Game

树状数组、离散化
#include <cstdio>#include <iostream>#include <cmath>#include <algorithm>using namespace std;const int MAXN = 50005;int n;int a[MAXN];int tree[MAXN], pre[MAXN], res[MAXN];int lowbit(int i){    return i & (-i);}void add(int pos, int val){    while (pos <= n)    {        tree[pos] = max(tree[pos], val);        pos += lowbit(pos);    }}int solve(int i){    int r = 0;    while (i > 0)    {        r = max(r, tree[i]);        i -= lowbit(i);    }    return r;}struct node{    int idx, l, r;    bool operator < (const node & e) const    {        return l > e.l;    }    void getin()    {        scanf("%d%d", &l, &r);    }}query[MAXN];int main(){#ifndef ONLINE_JUDGE    freopen("in.txt", "r", stdin);#endif    int t;    scanf("%d", &t);    while (t--)    {        scanf("%d", &n);        for (int i = 1; i<= n; ++i)        {            scanf("%d", a+i);        }        int q;        scanf("%d", &q);        for (int i = 0; i< q; ++i)        {            query[i].getin(); query[i].idx = i;        }        sort(query, query+q);        memset(tree, 0, sizeof tree);        memset(pre, 0, sizeof pre);        for (int i = 0, j = n; i< q; )        {            for (; j>0 && j >= query[i].l; --j)            {                for(int k = 1; k*k <= a[j]; ++k)                {                    if (a[j] % k == 0)                    {                        if (pre[k])                        {                            add(pre[k], k);                        }                        pre[k] = j;                        if (k != a[j]/k)                        {                            if (pre[a[j]/k])                            {                                add(pre[a[j]/k], a[j]/k);                            }                            pre[a[j]/k] = j;                        }                    }                }            }            while (i < q && query[i].l > j)            {                res[query[i].idx] = solve(query[i].r);                ++i;            }        }        for (int i = 0; i < q; ++i)            printf("%d\n", res[i]);    }    return 0;}


hdu 4638 Group

与上一题类似
#include <cstdio>#include <algorithm>using namespace std;const int MAXN = 100005;int sum[MAXN], a[MAXN];int ans[MAXN];int vis[MAXN];int n, m;// sum[i] 代表 struct qy{int s, e, id;bool operator < (const qy & v) const{return s < v.s;}void getin(int k) {id = k;scanf("%d%d", &s, &e);}}q[MAXN];int lowbit(int i) {return i &(-i);}void add(int i, int val){while (i<= n){sum[i] += val;i += lowbit(i);}}int query(int i){int num = 0;while (i > 0){num += sum[i];i -= lowbit(i);}return num;}int main(){#ifndef ONLINE_JUDGEfreopen("in.txt", "r", stdin);#endifint t;scanf("%d", &t);while (t--){scanf("%d%d", &n, &m);for (int i = 1; i<= n; ++i){scanf("%d", a+i);}memset(sum, 0, sizeof sum);memset(vis, 0, sizeof vis);for (int i = 1; i<= m; ++i){q[i].getin(i);}sort(q+1, q+1+m);int k = m;for (int i = n; i>= 1; --i){int tp = a[i];vis[tp] = i;add(i, 1);if (vis[tp+1]) add(vis[tp+1], -1);if (vis[tp-1]) add(vis[tp-1], -1);while (k >= 1 && q[k].s == i){ans[q[k].id] = query(q[k].e) - query(i-1);k--;}}for (int i = 1; i<= m; ++i){printf("%d\n", ans[i]);}}return 0;}


hdu 4777 Rabbit Kingdom

树状数组求解区间内互质的数个数
#include <cstdio>#include <iostream>#include <cmath>#include <map>#include <algorithm>#include <vector>using namespace std;const int MAXN = 200010;int n, m;int sum[MAXN], isprm[MAXN], prime[MAXN], nprm;int num[MAXN], cp[MAXN][15], LL[MAXN], RR[MAXN], U[MAXN], O[MAXN], ans[MAXN];vector<int> mmp[MAXN];struct _query{int l, r, d;bool operator < (const _query & a) const{return r < a.r;}}query[MAXN];void getprime(){nprm = 0;for (int i = 2; i< 500; ++i){if (isprm[i] == 0) prime[nprm++] = i;for (int j = 0; j<nprm && i*prime[j] < MAXN; ++j){isprm[i*prime[j]] = 1;if (i % prime[j] == 0) break;}}}int lowbit(int c){return c&-c; }void add(int u, int val){if (!u) return;while (u <= n){sum[u] += val;u += lowbit(u);}}int getsum(int u){int res = 0;while (u > 0){res += sum[u];u -= lowbit(u);}return res;}void dividePrime(int idx){int tp = num[idx];cp[idx][0] = 0;for (int i = 0; i< nprm && prime[i]*prime[i]<=tp ; ++i){if (tp % prime[i] == 0){cp[idx][++cp[idx][0]] = prime[i];while (tp % prime[i] == 0) tp/=prime[i];}}if (tp != 1) cp[idx][++cp[idx][0]] = tp;}int main(){#ifndef ONLINE_JUDGE    freopen("in.txt", "r", stdin);#endifint idx;getprime();while (scanf("%d%d", &n, &m) && (n+m)){for (int i = 1; i<= n; ++i) scanf("%d", num+i);for (int i = 0; i< m; ++i){scanf("%d%d", &query[i].l, &query[i].r);query[i].d = i;}sort(query, query+m);memset(sum, 0, sizeof sum);for (int i = 1; i<= n; ++i) dividePrime(i), LL[i] = 0, RR[i] = n+1;for (int i = 0; i< MAXN; ++i)U[i] = 0, O[i] = n+1;for (int i = 1; i<= n; ++i){for (int j = 1, k=cp[i][0]; j<= k; ++j){LL[i] = max(LL[i], U[cp[i][j]]);U[cp[i][j]] = i;}}for (int i = n; i>= 1; --i){for (int j = 1, k=cp[i][0]; j<= k; ++j){RR[i] = min(RR[i], O[cp[i][j]]);O[cp[i][j]] = i;}}for (int i = 1; i<= n; ++i) mmp[i].clear();for (int i = 1; i<= n; ++i) mmp[RR[i]].push_back(i);idx = 1;for (int i = 0; i< m; ++i){while (idx <= query[i].r && idx <= n){add(LL[idx], 1);for (int a, j = 0, k=mmp[idx].size(); j<k; ++j){a = mmp[idx][j];add(LL[a], -1);add(a, 1);}++idx;}ans[query[i].d] = getsum(query[i].r) - getsum(query[i].l-1);ans[query[i].d] = query[i].r-query[i].l+1 - ans[query[i].d];}for (int i = 0; i< m; ++i) printf("%d\n", ans[i]);}    return 0;}


原创粉丝点击