题意:给出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|1 int 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; }
时间: 2024-09-28 02:15:36