結果

問題 No.1625 三角形の質問
ユーザー naoya_tnaoya_t
提出日時 2021-07-29 23:25:17
言語 C++17
(gcc 12.3.0 + boost 1.83.0)
結果
AC  
実行時間 4,216 ms / 6,000 ms
コード長 13,545 bytes
コンパイル時間 4,530 ms
コンパイル使用メモリ 251,800 KB
実行使用メモリ 306,176 KB
最終ジャッジ日時 2023-10-12 21:41:08
合計ジャッジ時間 60,251 ms
ジャッジサーバーID
(参考情報)
judge12 / judge15
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 2 ms
4,352 KB
testcase_01 AC 172 ms
24,384 KB
testcase_02 AC 1,330 ms
99,352 KB
testcase_03 AC 1,554 ms
106,392 KB
testcase_04 AC 993 ms
89,440 KB
testcase_05 AC 2,458 ms
175,748 KB
testcase_06 AC 4,193 ms
305,864 KB
testcase_07 AC 4,087 ms
305,672 KB
testcase_08 AC 4,216 ms
305,876 KB
testcase_09 AC 4,171 ms
305,796 KB
testcase_10 AC 4,127 ms
305,916 KB
testcase_11 AC 4,069 ms
306,176 KB
testcase_12 AC 4,168 ms
305,924 KB
testcase_13 AC 4,214 ms
305,964 KB
testcase_14 AC 4,064 ms
305,860 KB
testcase_15 AC 4,117 ms
305,740 KB
testcase_16 AC 435 ms
86,224 KB
testcase_17 AC 991 ms
124,660 KB
testcase_18 AC 698 ms
81,300 KB
testcase_19 AC 1,276 ms
143,480 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

#include <bits/stdc++.h>
using namespace std;

#define NDEBUG
#include <cassert>


typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> ii;
typedef pair<ll,ll> llll;
typedef pair<double,double> dd;

typedef vector<int> vi;
typedef vector<vector<int>> vvi;
typedef vector<ii> vii;
typedef vector<vector<ii>> vvii;
typedef vector<ll> vll;
typedef vector<vector<ll>> vvll;
typedef vector<bool> vb;
typedef vector<string> vs;
typedef vector<double> vd;

#define pb  push_back
#define eb  emplace_back
#define rep(var,n)  for(int var=0;var<(n);++var)
#define rep1(var,n)  for(int var=1;var<=(n);++var)
#define repC2(vari,varj,n)  for(int vari=0;vari<(n)-1;++vari)for(int varj=vari+1;varj<(n);++varj)
#define repC3(vari,varj,vark,n)  for(int vari=0;vari<(n)-2;++vari)for(int varj=vari+1;varj<(n)-1;++varj)for(int vark=varj+1;vark<(n);++vark)
#define ALL(c)  (c).begin(),(c).end()
#define RALL(c)  (c).rbegin(),(c).rend()
#define whole(f, x, ...)                                     \
    ([&](decltype((x)) whole) {                              \
        return (f)(begin(whole), end(whole), ##__VA_ARGS__); \
    })(x)
#define tr(i,c)  for(auto i=(c).begin(); i!=(c).end(); ++i)
#define found(s,e)  ((s).find(e)!=(s).end())
#define mset(arr,val)  memset(arr,val,sizeof(arr))
#define mid(x,y) ((x)+((y)-(x))/2)
#define IN(x,a,b) ((a)<=(x)&&(x)<=(b))
#define IN_(x,a,b) ((a)<=(x)&&(x)<(b))
#define tors(a) sort(ALL(a), greater<decltype(a[0])>())
#define nC2(n) ((ll)(n)*((n)-1)/2)

#define clamp(v,lo,hi) min(max(v,lo),hi)
#define ABS(x) max((x),-(x))
#define PQ(T) priority_queue<T,vector<T>,greater<T>>
#define CLEAR(a) remove_reference_t<decltype(a)>().swap(a)
template <typename T>
vector<T> vec(size_t len, T elem) { return vector<T>(len, elem); }

template<typename T1, typename T2> inline void amin(T1 & a, T2 const & b) { if (a>b) a=b; }
template<typename T1, typename T2> inline void amax(T1 & a, T2 const & b) { if (a<b) a=b; }

template <typename T>
void erase_one(multiset<T>& ms, T val) {
    auto iter = ms.find(val);
    if (iter != ms.end()) ms.erase(iter);
}

inline ll square(ll x) { return x * x; }
inline ll gcd(ll a, ll b) { while(a) swap(a, b%=a); return b; }
inline ll lcm(ll a, ll b) { return a/gcd(a,b)*b; }
template <typename T>
inline T mod(T a, T b) { return ((a % b) + b) % b; }


#define is_digit(c) ('0'<=(c)&&(c)<='9')
#define is_whitespace(c) ((c)==' '||(c)=='\n'||(c)=='\r'||(c)=='\t'||(c)==EOF)
void reader(int& x){
  x=0;
  bool neg=false; for(;;){ int k=getchar(); if(k=='-'){ neg=true; break; } if (is_digit(k)){ x=k-'0'; break;} }
  for(;;){ int k=getchar(); if (!is_digit(k)) break; x=x*10+k-'0'; }
  if(neg) x=-x; }
void reader(long long& x){
  x=0;
  bool neg=false; for(;;){ int k=getchar(); if(k=='-'){ neg=true; break; } if (is_digit(k)){ x=k-'0'; break; } }
  for(;;){ int k=getchar(); if (!is_digit(k)) break; x=x*10+k-'0'; }
  if(neg) x=-x; }
void reader(unsigned long long& x){
  x=0;
  for(;;){ int k=getchar(); if (is_digit(k)){ x=(unsigned long long)(k-'0'); break; } }
  for(;;){ int k=getchar(); if (!is_digit(k)) break; x=x*10+k-'0'; } }
int reader(char s[]){
  int c,i=0;
  for(;;){ c=getchar(); if (!is_whitespace(c)) break; } s[i++]=c;
  for(;;){ c=getchar(); if (is_whitespace(c)) break; s[i++]=c; }
  s[i]='\0'; return i; }
int reader(string& s){
  int c;
  for(;;){ c=getchar(); if (!is_whitespace(c)) break; } s.push_back(c);
  for(;;){ c=getchar(); if (is_whitespace(c)) break; s.push_back(c); }
  return s.size(); }
void reader(char& c){
  for(;;){ c=getchar(); if (!is_whitespace(c)) break; } }

void writer(int x, char c=0){
  int s=0; bool neg=false; char f[10]; if(x<0) neg=true,x=-x; if(x==0) f[s++]='0'; else while(x) f[s++]='0'+x%10,x/=10;
  if(neg) putchar('-'); while(s--) putchar(f[s]); if(c) putchar(c); }
void writer(long long x, char c=0){
  int s=0; bool neg=false; char f[20]; if(x<0) neg=true,x=-x; if(x==0) f[s++]='0'; else while(x) f[s++]='0'+x%10,x/=10;
  if(neg) putchar('-'); while(s--) putchar(f[s]); if(c) putchar(c); }
void writer(unsigned long long x, char c=0){
  int s=0; char f[20]; if(x==0) f[s++]='0'; else while(x) f[s++]='0'+x%10,x/=10;
  while(s--) putchar(f[s]); if(c) putchar(c); }
void writer(const string& x, char c=0){
  for(int i=0;i<x.size();++i) putchar(x[i]); if(c) putchar(c); }
void writer(const char x[], char c=0){
  for(int i=0;x[i]!='\0';++i) putchar(x[i]); if(c) putchar(c); }

template <class T,class S> void reader(T& x, S& y){ reader(x); reader(y); }
template <class T,class S,class U> void reader(T& x, S& y, U& z){ reader(x); reader(y); reader(z); }
template <class T,class S,class U,class V> void reader(T& x, S& y, U& z, V& w){ reader(x); reader(y); reader(z); reader(w); }
template <class T> vector<T> readerArray(int n){
  vector<T> ret(n); for(int i=0;i<n;++i) reader(ret[i]); return ret; }
template <class T> vector<vector<T>> readerMatrix(int n,int m=0){
  if (m==0) m = n; vector<vector<T>> ret(n); for(int i=0;i<n;++i) ret[i] = readerArray<T>(m); return ret; }

template <class T> void writerLn(T x){ writer(x,'\n'); }
template <class T,class S> void writerLn(T x, S y){ writer(x,' '); writer(y,'\n'); }
template <class T,class S,class U> void writerLn(T x, S y, U z){ writer(x,' '); writer(y,' '); writer(z,'\n'); }
template <class T,class S,class U,class V> void writerLn(T x, S y, U z, V v){ writer(x,' '); writer(y,' '); writer(z,' '); writer(v,'\n'); }
template <class T> void writerArrayLn(T x[], int n){
  if(n==0){ putchar('\n'); return; }
  for(int i=0;i<n-1;++i) writer(x[i],' '); writer(x[n-1],'\n'); }
template <class T> void writerArrayLn(vector<T>& x){ writerArrayLn(x.data(),(int)x.size()); }
template <class T> void writerArrayLnV(T x[], int n){ for(int i=0;i<n;++i) writerLn(x[i]); }
template <class T> void writerArrayLnV(vector<T>& x){ for(T xi: x) writerLn(xi); }
template <class T> void writerMatrix(vector<vector<T>>& x){
  int n = x.size(); if (n == 0) return;
  int m = x[0].size(); for (int i=0; i<n; ++i) writerArrayLn(x[i]); }

void readerEdges(size_t M,vector<int>& a,vector<int>& b,bool decrement=true){
  a.resize(M); b.resize(M);
  for(int i=0;i<M;++i){ reader(a[i]); reader(b[i]); if(decrement){ --a[i]; --b[i]; } } }
template <class W> void readerEdges(size_t M,vector<int>& a,vector<int>& b,vector<W>& c,bool decrement=true){
  a.resize(M); b.resize(M); c.resize(M);
  for(int i=0;i<M;++i){ reader(a[i]); reader(b[i]); reader(c[i]); if(decrement){ --a[i]; --b[i]; } } }
template <class S,class T> void readerEdges(size_t M,vector<int>& a,vector<int>& b,vector<S>& c,vector<T>& d,bool decrement=true){
  a.resize(M); b.resize(M); c.resize(M); d.resize(M);
  for(int i=0;i<M;++i){ reader(a[i]); reader(b[i]); reader(c[i]); reader(d[i]); if(decrement){ --a[i]; --b[i]; } } }

vector<vector<int>> make_nxt(int N, int M, vector<int>& a, vector<int>& b){
  vector<vector<int>> nxt(N);
  for(int i=0;i<M;++i){ nxt[a[i]].push_back(b[i]); nxt[b[i]].push_back(a[i]); }
  return nxt; }
template <class T> vector<vector<pair<int,T>>> make_nxt(int N, int M, vector<int>& a, vector<int>& b, vector<T>& c){
  vector<vector<pair<int,T>>> nxt(N);
  for(int i=0;i<M;++i){ nxt[a[i]].emplace_back(b[i],c[i]); nxt[b[i]].emplace_back(a[i],c[i]); }
  return nxt; }

#define rep_(i,a,b) for(int i=a;i<b;i++)
#define rrep(i,a,b) for(int i=a;i>=b;i--)
#define fore(i,a) for(auto &i:a)

#define def INT_MIN
using V = int;
inline V comp(V l, V r) { return max(l, r); }

struct SegTree {
    int NV;
    vector<V> val;
    void init(int n) {
        NV = 1;
        while (NV < n) NV *= 2;
        val = vector<V>(NV * 2, def);
    }
    V get(int x, int y, int l, int r, int k) {
        if (r <= x || y <= l) return def;
        if (x <= l && r <= y) return val[k];
        return comp(
            get(x, y, l, (l + r) / 2, k * 2),
            get(x, y, (l + r) / 2, r, k * 2 + 1)
        );
    }
    V get(int x, int y) { return get(x, y, 0, NV, 1); }
    void update(int i, V v) { i += NV; val[i] = v; while (i>1)i >>= 1, val[i] = comp(val[i * 2], val[i * 2 + 1]); }
    void add(int i, V v) { update(i, comp(val[i + NV], v)); }
    V operator[](int x) { return get(x, x + 1); }
};

struct Healthy2DSegTree {
    int NV;
    vector<SegTree> st;
    vector<vector<int>> index;

    void init(vector<vector<int>> &v) {
        int n = v.size();
        NV = 1; while (NV < n) NV *= 2;
        index.resize(2 * NV);
        rep_(i, 0, n) fore(j, v[i]) index[i + NV].push_back(j);
        rrep(i, NV * 2 - 1, 1) {
            sort(index[i].begin(), index[i].end());
            index[i].erase(unique(index[i].begin(), index[i].end()), index[i].end());
            fore(j, index[i]) index[i / 2].push_back(j);
        }
        st.resize(2 * NV);
        rep_(i, 1, NV * 2) st[i].init(index[i].size());
    }
    void update(int x, int y, V v) {
        assert(x < NV);
        x += NV;
        while (x) {
            int yy = lower_bound(index[x].begin(), index[x].end(), y) - index[x].begin();
            assert(yy != index[x].size());
            assert(y == index[x][yy]);
            st[x].update(yy, v);
            x >>= 1;
        }
    }
    void add(int x, int y, V v) {
        assert(x < NV);
        x += NV;
        while (x) {
            int yy = lower_bound(index[x].begin(), index[x].end(), y) - index[x].begin();
            assert(yy != index[x].size());
            assert(y == index[x][yy]);
            st[x].add(yy, v);
            x >>= 1;
        }
    }
    V get(int sx, int tx, int sy, int ty, int k, int l, int r) {
        assert(k < NV * 2);
        assert(l < r);
        if (r <= sx or tx <= l) return def;
        if (sx <= l and r <= tx) {
            int syy = lower_bound(index[k].begin(), index[k].end(), sy) - index[k].begin();
            int tyy = lower_bound(index[k].begin(), index[k].end(), ty) - index[k].begin();
            return st[k].get(syy, tyy);
        }
        int md = (l + r) / 2;
        V le = get(sx, tx, sy, ty, k * 2, l, md);
        V ri = get(sx, tx, sy, ty, k * 2 + 1, md, r);
        return comp(le, ri);
    }
    V get(int sx, int tx, int sy, int ty) {
        return get(sx, tx, sy, ty, 1, 0, NV);
    }
};

template <typename T>
size_t uniq(vector<T>& a, bool do_sort=true) {
    if (do_sort) sort(a.begin(), a.end());
    a.erase(unique(a.begin(), a.end()), a.end());
    return a.size();
}


inline ll calc_area(vi& triangle) {
    ll x1 = triangle[2] - triangle[0];
    ll y1 = triangle[3] - triangle[1];
    ll x2 = triangle[4] - triangle[0];
    ll y2 = triangle[5] - triangle[1];
    return ABS(x1 * y2 - x2 * y1);
}

void solve(int N, int Q, vvi& triangles, vvi& queries) {
    set<int> xs;
    set<ll> ys;
    vll area(N, 0);
    using P = tuple<int, int, ll>;
    vector<P> triangles_in_queries;
    rep(i, N) {
        for (int j = 0; j < 6; j += 2) {
            xs.insert(triangles[i][j]);
        }
        area[i] = calc_area(triangles[i]);
        ys.insert(area[i]);
    }
    rep(i, Q) {
        int L = queries[i].size();
        if (L == 6) {
            int xmin = INT_MAX, xmax = INT_MIN;
            for (int j = 0; j < 6; j += 2) {
                int x = queries[i][j];
                xs.insert(x);
                amin(xmin, x);
                amax(xmax, x);
            }
            ll q_area = calc_area(queries[i]);
            triangles_in_queries.eb(xmin, xmax, q_area);
            ys.insert(q_area);

            CLEAR(queries[i]);
        } else {
            xs.insert(queries[i][0]);
            xs.insert(queries[i][1]);
        }
    }
    xs.insert(INT_MIN);
    xs.insert(INT_MAX);
    ys.insert(LLONG_MIN);
    ys.insert(LLONG_MAX);

    map<int, int> zx;
    int zxid = 0;
    for (int x : xs) zx[x] = zxid++;

    CLEAR(xs);

    map<ll, int> zy;
    int zyid = 0;
    vll zyR; zyR.reserve(ys.size());
    for (ll y : ys) {
        zy[y] = zyid++;
        zyR.pb(y);
    }

    CLEAR(ys);


    vvi index(zxid);

    rep(i, N) {
        int xmin = INT_MAX, xmax = INT_MIN;
        for (int j = 0; j < 6; j += 2) {
            int x = zx[triangles[i][j]];
            amin(xmin, x);
            amax(xmax, x);
        }
        index[xmin].push_back(xmax);
    }
    for (auto [xmin, xmax, _q_area]: triangles_in_queries) {
        index[zx[xmin]].push_back(zx[xmax]);
    }
    rep(x, zxid) uniq(index[x]);

    Healthy2DSegTree seg;
    seg.init(index);

    rep(i, N) {
        int xmin = INT_MAX, xmax = INT_MIN;
        for (int j = 0; j < 6; j += 2) {
            int x = zx[triangles[i][j]];
            amin(xmin, x);
            amax(xmax, x);
        }
        seg.add(xmin, xmax, zy[area[i]]);
    }

    CLEAR(triangles);
    CLEAR(area);

    int q = 0;
    rep(i, Q) {
        int L = queries[i].size();
        int xmin = INT_MAX, xmax = INT_MIN;
        if (L == 0) {
            auto [xmin, xmax, q_area] = triangles_in_queries[q++];
            seg.add(zx[xmin], zx[xmax], zy[q_area]);
        } else {
            int l = zx[queries[i][0]], r = zx[queries[i][1]];
            int res = seg.get(l, r, l, r+1);
            ll resR = (res >= 0) ? zyR[res] : LLONG_MIN;
            if (resR < 0) resR = -1;
            printf("%lld\n", resR);
        }
    }
}

int main() {
    int N, Q;
    reader(N, Q);
    vvi triangles(N, vi(6));
    rep(i, N) { triangles[i] = readerArray<int>(6); }
    vvi queries(Q);
    rep(i, Q) {
        int op;
        reader(op);
        if (op == 1) {
            queries[i] = readerArray<int>(6);
        } else {
            queries[i] = readerArray<int>(2);
        }
    }
    solve(N, Q, triangles, queries);
    return 0;
}
0