码队的新桌游

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

银联比赛-A码队女友的王者之路

银联比赛-B自学图论的码队弟弟

「UMLCSSA桌游夜」

求DBG桌游《巴巴罗萨》详细规则 越详细越好!新手 不说的详细完全理解不能。。。。。。

P1922 女仆咖啡厅桌游吧