제출 #607407

#제출 시각아이디문제언어결과실행 시간메모리
607407yuto1115팀들 (IOI15_teams)C++17
77 / 100
2803 ms524288 KiB
#include "teams.h" #include "bits/stdc++.h" #define rep(i, n) for(ll i = 0; i < ll(n); ++i) #define rep2(i, s, n) for(ll i = ll(s); i < ll(n); ++i) #define rrep(i, n) for(ll i = ll(n)-1; i >= 0; --i) #define pb push_back #define eb emplace_back #define all(a) a.begin(),a.end() #define SZ(a) int(a.size()) using namespace std; using ll = long long; using P = pair<int, int>; using vi = vector<int>; using vvi = vector<vi>; using vl = vector<ll>; using vvl = vector<vl>; using vp = vector<P>; using vvp = vector<vp>; using vb = vector<bool>; using vvb = vector<vb>; using vs = vector<string>; const int inf = 1001001001; const ll linf = 1001001001001001001; template<class T> bool chmin(T &a, T b) { if (a > b) { a = b; return true; } return false; } template<class T> bool chmax(T &a, T b) { if (a < b) { a = b; return true; } return false; } class segtree { struct node { ll lrd; node *cl; node *cr; node(int l, int r, int d) : lrd((ll(l) << 40) + (ll(r) << 20) + d), cl(nullptr), cr(nullptr) {} }; int n; node *root; node *build(int l, int r, const vi::iterator &a, const vi::iterator &b) { if (a == b) return nullptr; node *res = new node(l, r, b - a); if (r - l > 1) { int m = (l + r) / 2; auto c = lower_bound(a, b, m); res->cl = build(l, m, a, c); res->cr = build(m, r, c, b); } return res; } int count(int l, int r, node *nd) { if (nd == nullptr) return 0; int nl = nd->lrd >> 40; int nr = (nd->lrd >> 20) - (nl << 20); if (r <= nl or nr <= l) return 0; if (l <= nl and nr <= r) return nd->lrd - (nd->lrd >> 20 << 20); return count(l, r, nd->cl) + count(l, r, nd->cr); } public: segtree(int _n, const vi::iterator &a, const vi::iterator &b) : n(_n) { root = build(0, n, a, b); } int count(int l, int r) { assert(0 <= l and l <= r and r <= n); return count(l, r, root); } }; vector<segtree> st; int sz = 1; void merge(vi &v, const vi &a, const vi &b) { int ai = 0, bi = 0; v.reserve(SZ(a) + SZ(b)); while (ai < SZ(a) or bi < SZ(b)) { if (ai < SZ(a) and bi < SZ(b)) { if (a[ai] < b[bi]) v.pb(a[ai++]); else v.pb(b[bi++]); } else if (ai < SZ(a)) { v.pb(a[ai++]); } else { v.pb(b[bi++]); } } } void build(const vvi &v) { vvi ls(2 * sz); rep(i, sz) ls[sz + i] = v[i]; for (int i = sz - 1; i >= 1; --i) { merge(ls[i], ls[2 * i], ls[2 * i + 1]); } rep(i, 2 * sz) st.eb(sz, all(ls[i])); } int n; vi a, b; int count(int xl, int xr, int yl, int yr) { assert(0 <= xl and xl <= xr and xr <= sz); assert(0 <= yl and yl <= yr and yr <= sz); // cerr << xl << ' ' << xr << ' ' << yl << ' ' << yr << ' '; yl += sz, yr += sz; int res = 0; while (yl < yr) { if (yl & 1) res += st[yl++].count(xl, xr); if (yr & 1) res += st[--yr].count(xl, xr); yl >>= 1, yr >>= 1; } // cerr << res << endl; // int res = 0; // rep(i, n) if (xl <= a[i] and a[i] < xr and yl <= b[i] and b[i] < yr) ++res; return res; } void init(int N, int A[], int B[]) { n = N; a = vi(A, A + N); b = vi(B, B + N); for (int &i: b) ++i; while (sz <= n + 1) sz *= 2; vvi v(sz); rep(i, n) v[b[i]].pb(a[i]); rep(i, sz) sort(all(v[i])); build(v); // cerr << "init : " << N << endl; } int max_yr(int xl, int xr, int yl, int ub) { assert(0 <= xl and xl <= xr and xr <= sz); assert(0 <= yl and yl <= sz); assert(ub > 0); yl += sz; while (true) { if ((yl & -yl) == yl) return sz; while (~yl & 1) yl >>= 1; int now = st[yl].count(xl, xr); if (now < ub) { ub -= now; ++yl; continue; } while (yl < sz) { yl *= 2; now = st[yl].count(xl, xr); if (now < ub) { ub -= now; ++yl; } } return yl - sz; } } int can(int m, int K[]) { vi k = vi(K, K + m); sort(all(k)); // {x, max_y, rem in max_y} vvi v; v.pb({0, n + 1, 0}); for (int i: k) { // cerr << "i : " << i << endl; // for (auto t: v) cerr << "v : " << t[0] << ' ' << t[1] << ' ' << t[2] << endl; while (v.back()[1] < i + 1) v.pop_back(); int now = i + 1; int rem = i; while (true) { if (now > n + 1) return 0; assert(v.back()[1] >= now); int sum = count(v.back()[0] + 1, i + 1, now, v.back()[1] + 1) + v.back()[2]; if (sum < rem) { rem -= sum; now = v.back()[1] + 1; v.pop_back(); continue; } int psum = count(v.back()[0] + 1, i + 1, now, v.back()[1]); if (psum < rem) { v.back()[0] = i; v.back()[2] = sum - rem; } else { int ok = max_yr(v.back()[0] + 1, i + 1, now, rem) + 1; v.eb(vi{i, ok - 1, count(v.back()[0] + 1, i + 1, now, ok) - rem}); } break; } } // cerr << "i : end" << endl; // for (auto t: v) cerr << "v : " << t[0] << ' ' << t[1] << ' ' << t[2] << endl; return 1; }

컴파일 시 표준 에러 (stderr) 메시지

teams.cpp: In member function 'segtree::node* segtree::build(int, int, const iterator&, const iterator&)':
teams.cpp:57:38: warning: conversion from '__gnu_cxx::__normal_iterator<int*, std::vector<int> >::difference_type' {aka 'long int'} to 'int' may change value [-Wconversion]
   57 |         node *res = new node(l, r, b - a);
      |                                    ~~^~~
teams.cpp: In member function 'int segtree::count(int, int, segtree::node*)':
teams.cpp:69:26: warning: conversion from 'll' {aka 'long long int'} to 'int' may change value [-Wconversion]
   69 |         int nl = nd->lrd >> 40;
      |                  ~~~~~~~~^~~~~
teams.cpp:70:34: warning: conversion from 'll' {aka 'long long int'} to 'int' may change value [-Wconversion]
   70 |         int nr = (nd->lrd >> 20) - (nl << 20);
      |                  ~~~~~~~~~~~~~~~~^~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...