結果
| 問題 |
No.1625 三角形の質問
|
| コンテスト | |
| ユーザー |
batasanblog
|
| 提出日時 | 2023-04-06 20:25:39 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 1,902 ms / 6,000 ms |
| コード長 | 5,416 bytes |
| コンパイル時間 | 4,223 ms |
| コンパイル使用メモリ | 271,512 KB |
| 最終ジャッジ日時 | 2025-02-11 23:20:22 |
|
ジャッジサーバーID (参考情報) |
judge5 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 1 |
| other | AC * 19 |
ソースコード
#include <bits/stdc++.h>
using namespace std;
#include <atcoder/all>
using namespace atcoder;
//using mint = static_modint<998244353>;
//using mint = modint;
using mint = static_modint<1000000007>;
using vm = vector<mint>;
using vvm = vector<vm>;
ostream &operator<<(ostream &o,const mint &m){cout<<m.val();return o;}
using ll = long long;
using vl = vector<ll>;
using vvl = vector<vl>;
using pl = pair<ll,ll>;
#define rep(i,n) for(ll i=0;i<(ll)(n);++i)
#define reps(i,s,n) for(ll i=(s);i<(ll)(n);++i)
#define rep1(i,n) for(ll i=1;i<=(ll)(n);++i)
#define chmin(x,y) x=min(x,y)
#define chmax(x,y) x=max(x,y)
const long long INF = 1e18;
// CUT begin
// 逆元を要求しない領域木
template <class S, S (*op)(S, S), S (*e)(), class Coordinate> class rangetree {
int n;
using Pt = std::pair<Coordinate, Coordinate>;
std::vector<Pt> _pts;
std::vector<std::vector<Pt>> _range2yxs;
std::vector<atcoder::segtree<S, op, e>> segtrees;
void _set(int v, Pt p, S val) {
auto i = std::distance(
_range2yxs[v].begin(),
std::lower_bound(_range2yxs[v].begin(), _range2yxs[v].end(), Pt{p.second, p.first}));
segtrees[v].set(i, val);
}
void _add(int v, Pt p, S val) {
auto i = std::distance(
_range2yxs[v].begin(),
std::lower_bound(_range2yxs[v].begin(), _range2yxs[v].end(), Pt{p.second, p.first}));
segtrees[v].set(i, op(segtrees[v].get(i), val));
}
S _prod(int v, Coordinate yl, Coordinate yr) const {
auto comp = [&](const Pt &l, const Pt &r) { return l.first < r.first; };
auto il = std::distance(
_range2yxs[v].begin(),
std::lower_bound(_range2yxs[v].begin(), _range2yxs[v].end(), Pt{yl, yl}, comp));
auto ir = std::distance(
_range2yxs[v].begin(),
std::lower_bound(_range2yxs[v].begin(), _range2yxs[v].end(), Pt{yr, yr}, comp));
return segtrees[v].prod(il, ir);
}
public:
rangetree() = default;
void add_point(Coordinate x, Coordinate y) noexcept { _pts.emplace_back(x, y); }
void build() {
std::sort(_pts.begin(), _pts.end());
_pts.erase(std::unique(_pts.begin(), _pts.end()), _pts.end());
n = _pts.size();
_range2yxs.resize(n * 2);
for (int i = 0; i < n; i++) _range2yxs[n + i] = {{_pts[i].second, _pts[i].first}};
for (int i = n - 1; i > 0; i--) {
auto &lch = _range2yxs[i * 2];
auto &rch = _range2yxs[i * 2 + 1];
std::merge(
lch.begin(), lch.end(), rch.begin(), rch.end(), std::back_inserter(_range2yxs[i]));
_range2yxs[i].erase(
std::unique(_range2yxs[i].begin(), _range2yxs[i].end()), _range2yxs[i].end());
}
for (const auto &v : _range2yxs) segtrees.emplace_back(v.size());
}
void set(Coordinate x, Coordinate y, S val) {
int i = std::distance(_pts.begin(), std::lower_bound(_pts.begin(), _pts.end(), Pt{x, y}));
assert(i < n and _pts[i] == std::make_pair(x, y));
for (i += n; i; i >>= 1) _set(i, {x, y}, val);
}
void add(Coordinate x, Coordinate y, S val) {
int i = std::distance(_pts.begin(), std::lower_bound(_pts.begin(), _pts.end(), Pt{x, y}));
assert(i < n and _pts[i] == std::make_pair(x, y));
for (i += n; i; i >>= 1) _add(i, {x, y}, val);
}
S prod(Coordinate xl, Coordinate xr, Coordinate yl, Coordinate yr) const {
auto comp = [](const Pt &l, const Pt &r) { return l.first < r.first; };
int l = n + std::distance(_pts.begin(),
std::lower_bound(_pts.begin(), _pts.end(), Pt{xl, yr}, comp));
int r = n + std::distance(_pts.begin(),
std::lower_bound(_pts.begin(), _pts.end(), Pt{xr, yr}, comp));
S ret = e();
while (l < r) {
if (l & 1) ret = op(ret, _prod(l++, yl, yr));
if (r & 1) ret = op(ret, _prod(--r, yl, yr));
l >>= 1, r >>= 1;
}
return ret;
}
S get(Coordinate x, Coordinate y) const { return prod(x, x + 1, y, y + 1); }
};
#ifdef DEBUG
#include <debug.hpp>
#endif
//struct S{
//ll minx,maxx;
//ll area;
//}
using S=ll;
S op(S a,S b){
return max(a,b);
}
S e(){
return -1;
}
int main(){
#ifdef DEBUG
cout << "--- Input ---" << endl;
#endif
ll N,Q;cin>>N>>Q;
vl X(N),Y(N),A(N);
rangetree<S,op,e,ll> seg;
rep(i,N){
ll a,b,c,d,e,f;cin>>a>>b>>c>>d>>e>>f;
ll x=min({a,c,e});
ll y=max({a,c,e});
ll area=abs((e-a)*(d-b)-(f-b)*(c-a));
seg.add_point(x,y);
X.at(i)=x;Y.at(i)=y;A.at(i)=area;
}
vl T(Q),L(Q),R(Q);
rep(qi,Q){
ll t;cin>>t;
T.at(qi)=t;
if(t==1){
ll a,b,c,d,e,f;cin>>a>>b>>c>>d>>e>>f;
ll x=min({a,c,e});
ll y=max({a,c,e});
ll area=abs((e-a)*(d-b)-(f-b)*(c-a));
seg.add_point(x,y);
X.push_back(x);Y.push_back(y);A.push_back(area);
}else{
cin>>L.at(qi)>>R.at(qi);
}
}
seg.build();
rep(i,N){
seg.add(X.at(i),Y.at(i),A.at(i));
}
#ifdef DEBUG
cout<<X<<Y<<A;
rep(i,N){
cout<<seg.get(X.at(i),Y.at(i))<<" ";
}
cout<<endl;
cout << "--- Logic ---" << endl;
#endif
ll p=N;
rep(qi,Q){
if(T.at(qi)==1){
seg.add(X.at(p),Y.at(p),A.at(p));
++p;
}else{
cout<<seg.prod(L.at(qi),R.at(qi)+1,L.at(qi),R.at(qi)+1)<<endl;
}
}
#ifdef DEBUG
cout << "--- Answer ---" << endl;
#endif
return 0;
}
//cout << fixed << setprecision(9);
batasanblog