码队的新桌游
Posted liulex
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了码队的新桌游相关的知识,希望对你有一定的参考价值。
树状数组、离散化、二维偏序
#include <bits/stdc++.h> ///即找x.a<y.b<x.c&&y.a<x.b<y.c的组数 using namespace std; struct Item int a, b, c; int id; int ans; explicit Item(int _a = 0, int _b = 0, int _c = 0) : a(_a), b(_b), c(_c) ; struct cmpa bool operator()(const Item &lhs, const Item &rhs) const return lhs.a > rhs.a || (lhs.a == rhs.a && lhs.b < rhs.b) || (lhs.a == rhs.a && lhs.b == rhs.b && lhs.c < rhs.c); ; struct cmpc bool operator()(const Item &lhs, const Item &rhs) const return lhs.c > rhs.c || (lhs.c == rhs.c && lhs.b < rhs.b) || (lhs.c == rhs.c && lhs.b == rhs.b && lhs.a < rhs.a); ; priority_queue<Item, vector<Item>, cmpa> Qin; priority_queue<Item, vector<Item>, cmpc> Qout; const int MAXN = 300100; int ca[MAXN]; int lsh[MAXN], lsc; Item za[MAXN]; unordered_map<int, int> lss; void addZ(int x, int v) while (x <= lsc) ca[x] += v; x += (x & -x); int getZ(int x) int ans = 0; while (x) ans += ca[x]; x -= (x & -x); return ans; int main() int n; scanf("%d", &n); for (int i = 0; i < n; ++i) scanf("%d%d%d", &za[i].a, &za[i].b, &za[i].c); Qin.push(za[i]); lsh[lsc++] = za[i].a; lsh[lsc++] = za[i].b; lsh[lsc++] = za[i].c; za[i].id = i; sort(lsh, lsh + lsc); lsc = unique(lsh, lsh + lsc) - lsh; for (int i = 0; i < lsc; ++i) lss[lsh[i]] = i + 1;///离散化 sort(za, za + n, [](const Item &a, const Item &b) return a.b < b.b; ); for (int i = 0; i < n; ++i) while (!Qin.empty()) Item xx = Qin.top(); if (za[i].b > xx.a) Qin.pop();///a小的先出来 addZ(lss[xx.b], 1);///加入树状数组,若z[a].b<=xx.a,则za[i]必输 Qout.push(xx); else break; while (!Qout.empty()) Item xx = Qout.top(); if (za[i].b >= xx.c) Qout.pop();///c小的先出来 addZ(lss[xx.b], -1);///减去,因为xx.c<=Z[a].b,则za[i]必赢 ///树状数组中元素都满足xx.c>za[i].b else break; za[i].ans = getZ(lss[za[i].c]) - getZ(lss[za[i].a]); sort(za, za + n, [](const Item &a, const Item &b) return a.id < b.id; ); for (int i = 0; i < n; ++i)printf("%d\n", za[i].ans-1); return 0;
以上是关于码队的新桌游的主要内容,如果未能解决你的问题,请参考以下文章
STEAM亲子桌游:超火英国orchard toys桌游不是1套是13套,在家免费DIY