首页 > 代码库 > poj3928pingpong区间和

poj3928pingpong区间和

  题意:给出n; n个人有n个不同的技能值  问 任取三个人 使得 中间那人的 技能值也在其他两人之间。

树状数组

#include <cstdio>#include <cstring>#include <algorithm>#include <climits>#include <string>#include <iostream>#include <map>#include <cstdlib>#include <list>#include <set>#include <queue>#include <stack>#include <math.h>using namespace std;typedef long long LL;const LL maxn = 100000 + 100;LL Max;LL c[maxn];LL zuomin[maxn],youmin[maxn],zuomax[maxn],youmax[maxn];LL lowbit(LL x){    return x&(-x);}void update(LL x, LL add){    while (x <= Max){        c[x] += add;        x += lowbit(x);    }}LL ask(LL x){    LL ans = 0;    while (x > 0){        ans += c[x];        x -= lowbit(x);    }    return ans;}int main(){    LL n;    LL a[maxn],Icase;    cin>>Icase;    while (Icase--){        cin>>n;        Max = -1;        for (LL i = 1; i <= n; i++)            cin >> a[i],Max = max(Max,a[i]);        memset(c, 0, sizeof(c));        for (LL i = 1; i <= n; i++){            zuomin[i] = ask(a[i]); zuomax[i]= ask(Max) - ask(a[i]);            update(a[i], 1);//边统计左边比他大和比他小的 ,边插        }        memset(c, 0, sizeof(c));        for (LL i = n; i >= 1; i--){            youmin[i] = ask(a[i]); youmax[i] = ask(Max) - ask(a[i]);            update(a[i], 1);        }        LL ans = 0;        for (LL i = 1; i <= n; i++){            ans += zuomin[i] * youmax[i];            ans += zuomax[i] * youmin[i];        }        cout << ans << endl;    }    return 0;}

线段树

#include <cstdio>#include <cstring>#include <algorithm>#include <climits>#include <string>#include <iostream>#include <map>#include <cstdlib>#include <list>#include <set>#include <queue>#include <stack>#include <math.h>using namespace std;typedef long long LL;const int maxn = 100000 + 100;#define lson l,mid,rt<<1#define rson mid+1,r,rt<<1|1int sum[maxn * 4];int zuomin[maxn], youmin[maxn], zuomax[maxn], youmax[maxn];void up(int rt){    sum[rt] = sum[rt << 1] + sum[rt << 1 | 1];}void build(int l, int r, int rt){    sum[rt] = 0;    if (l == r) return;    int mid = (l + r) >> 1;    build(lson);    build(rson);}void update(int pos, int add, int l, int r, int rt){    if (l == r){        sum[rt] = 1; return;    }    int mid = (l + r) >> 1;    if (pos <= mid) update(pos, add, lson);    else update(pos, add, rson);    up(rt);}int ask(int L, int R, int l, int r, int rt){    if (L <= l&&r <= R) return sum[rt];    int mid = (l + r) >> 1;    int ans = 0;    if (L <= mid) ans += ask(L, R, lson);    if (R > mid) ans += ask(L, R, rson);    return ans;}int main(){    int Icase;    int n, Max;    int a[maxn];    cin >> Icase;    while (Icase--){        cin >> n;        Max = -1;        for (int i = 1; i <= n; i++) scanf("%d", &a[i]), Max = max(Max, a[i]);        build(1, Max, 1);        for (int i = 1; i <= n; i++){            zuomin[i] = ask(1,a[i],1,Max,1); zuomax[i] = ask(1,Max,1,Max,1) - ask(1,a[i],1,Max,1);            update(a[i], 1,1,Max,1);        }        build(1, Max, 1);        for (int i = n; i >= 1; i--){            youmin[i] = ask(1,a[i],1,Max,1); youmax[i] = ask(1,Max,1,Max,1) - ask(1,a[i],1,Max,1);            update(a[i], 1,1,Max,1);        }        LL ans = 0;        for (int i = 1; i <= n; i++){            ans += zuomin[i] * youmax[i];            ans += zuomax[i] * youmin[i];        }        cout << ans << endl;    }    return 0;}

 

poj3928pingpong区间和