Submission #536692

# Submission time Handle Problem Language Result Execution time Memory
536692 2022-03-13T22:02:56 Z Evang trapezoid (balkan11_trapezoid) C++17
100 / 100
202 ms 17596 KB
#include <bits/extc++.h>
using namespace std;
using namespace __gnu_pbds;

#ifdef _DEBUG
#define dout(x) clog << "Line " << __LINE__ << ": " << #x << "=" << (x) << el
#else
#define dout(x)
#endif

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
#define uid(a,b) uniform_int_distribution<int>(a,b)(rng)

#define ins insert
#define ssize(x) (int((x).size()))
#define bs(args...) binary_search(args)
#define lb(args...) lower_bound(args)
#define ub(args...) upper_bound(args)
#define all(x) (x).begin(),(x).end()
#define mp(a, b) make_pair(a, b)
#define mt(args...) make_tuple(args)
#define pb push_back
#define eb emplace_back
#define ff first
#define ss second
#define die exit(0)

template<typename T>
using vc = vector<T>;
template<typename T>
using uset = unordered_set<T>;
template<typename A, typename B>
using umap = unordered_map<A, B>;
template<typename T, typename Comp>
using pq = std::priority_queue<T, vc<T>, Comp>;
template<typename T>
using maxpq = pq<T, less<T>>;
template<typename T>
using minpq = pq<T, greater<T>>;
template<typename T>
using oset = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

using db = double;
using ld = long double;
using ll = long long;
using ull = unsigned long long;
using pi = pair<int, int>;
using pll = pair<ll, ll>;
using vi = vc<int>;
using vll = vc<ll>;
using vpi = vc<pi>;
using vpll = vc<pll>;
using str = string;

constexpr char el = '\n';
constexpr char sp = ' ';
constexpr int inf = 0x3f3f3f3f;
constexpr ll llinf = 0x3f3f3f3f3f3f3f3fLL;
// ---------------------------------------------------------------------


const int N = 1e5+5;
const int mod = 30013;
int n, n2;
struct trap {
    int a, b, c, d;
} a[N];
vi qs[N];
struct node {
    int max=0, cnt=0;
} tr[800'005], dp[N];
map<pi, node> mp;

node cmb(node x, node y){
    if(x.max == y.max)
        return node{x.max, (x.cnt+y.cnt)%mod};
    if(x.max > y.max)
        return x;
    return y;
}

void upd(int i, node x){
    i += n2;
    tr[i] = cmb(x, tr[i]);

    for(i /= 2; i > 0; i /= 2)
        tr[i] = cmb(tr[2*i], tr[2*i+1]);
}

node qry(int r){
    r += n2;
    int l = n2;
    node ans;
    while(l<=r){
        if(l&1)
            ans = cmb(ans, tr[l++]);
        if(r&1^1)
            ans = cmb(ans, tr[r--]);
        l /= 2;
        r /= 2;
    }
    return ans;
}

void unik(vi &v){
    sort(all(v));
    vi u{v[0]};
    for(int i = 1; i < ssize(v); ++i)
        if(v[i]^v[i-1])
            u.pb(v[i]);
    swap(u, v);
}

signed main() {
    ios::sync_with_stdio(0); cin.tie(0);
    cout << fixed; clog << fixed; clog << unitbuf;
#ifdef _DEBUG
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
    freopen("debug.txt", "w", stderr);
#else
    //freopen(".in", "r", stdin);
    //freopen(".out", "w", stdout);
#endif

    cin >> n;
    vi cct{-inf, inf}, ccb{-inf, inf};
    for(int i = 1; i <= n; ++i) {
        cin >> a[i].a >> a[i].b >> a[i].c >> a[i].d;
        cct.pb(a[i].a);
        cct.pb(a[i].b);
        ccb.pb(a[i].c);
        ccb.pb(a[i].d);
    }
    a[0] = {-inf, -inf, -inf, -inf};
    ++n;
    sort(a, a+n, [](trap x, trap y){
        return x.b < y.b;
    });
    unik(cct);
    unik(ccb);
    n2 = 1;
    while(n2<2*n)
        n2 *= 2;
    for(int i = 0; i < n; ++i){
        a[i].a = lb(all(cct), a[i].a)-cct.begin();
        a[i].b = lb(all(cct), a[i].b)-cct.begin();
        a[i].c = lb(all(ccb), a[i].c)-ccb.begin();
        a[i].d = lb(all(ccb), a[i].d)-ccb.begin();
    }

    for(int i = 1; i < n; ++i){
        int p = 0;
        for(int u = i; u > 0; u /= 2)
            while(u+p<i&&a[u+p].b<a[i].a)
                p += u;
        while(a[p+1].b<a[i].a)
            ++p;
        qs[p].pb(a[i].c-1);
    }

    dp[0] = {0, 1};
    for(int i = 0; i < n; ++i){
        int p = 0;
        for(int u = i; u > 0; u /= 2)
            while(u+p<i&&a[u+p].b<a[i].a)
                p += u;

        if(i>0){
            dp[i] = mp[mp(p, a[i].c-1)];
            dp[i].max++;
        }

        upd(a[i].d, dp[i]);
        for(int j: qs[i])
            mp[mp(i, j)] = qry(j);
    }

    node ans = qry(2*n-1);
    cout << ans.max << sp << ans.cnt;

#ifdef _DEBUG
    clog << "Line " << __LINE__ << ":\n";
    for(int i = 0; i < n; ++i)
        clog << dp[i].max << sp << dp[i].cnt << el;
    clog << el;
#endif
}

Compilation message

trapezoid.cpp: In function 'node qry(int)':
trapezoid.cpp:97:13: warning: suggest parentheses around arithmetic in operand of '^' [-Wparentheses]
   97 |         if(r&1^1)
      |            ~^~
# Verdict Execution time Memory Grader output
1 Correct 2 ms 2644 KB Output is correct
2 Correct 2 ms 2692 KB Output is correct
3 Correct 2 ms 2772 KB Output is correct
4 Correct 3 ms 2772 KB Output is correct
5 Correct 4 ms 3028 KB Output is correct
6 Correct 6 ms 3216 KB Output is correct
7 Correct 7 ms 3348 KB Output is correct
8 Correct 9 ms 3468 KB Output is correct
9 Correct 18 ms 4380 KB Output is correct
10 Correct 33 ms 6152 KB Output is correct
11 Correct 54 ms 6732 KB Output is correct
12 Correct 109 ms 10368 KB Output is correct
13 Correct 112 ms 11944 KB Output is correct
14 Correct 131 ms 13476 KB Output is correct
15 Correct 147 ms 14268 KB Output is correct
16 Correct 169 ms 14952 KB Output is correct
17 Correct 158 ms 15600 KB Output is correct
18 Correct 149 ms 16344 KB Output is correct
19 Correct 163 ms 16356 KB Output is correct
20 Correct 202 ms 17596 KB Output is correct