結果

問題 No.1074 増殖
ユーザー ningenMeningenMe
提出日時 2020-06-15 00:56:17
言語 C++17
(gcc 12.3.0 + boost 1.83.0)
結果
AC  
実行時間 323 ms / 2,000 ms
コード長 10,499 bytes
コンパイル時間 2,541 ms
コンパイル使用メモリ 213,772 KB
実行使用メモリ 24,088 KB
最終ジャッジ日時 2023-09-10 18:18:00
合計ジャッジ時間 5,958 ms
ジャッジサーバーID
(参考情報)
judge13 / judge12
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 20 ms
23,908 KB
testcase_01 AC 20 ms
24,080 KB
testcase_02 AC 20 ms
23,864 KB
testcase_03 AC 20 ms
23,832 KB
testcase_04 AC 20 ms
23,880 KB
testcase_05 AC 20 ms
23,880 KB
testcase_06 AC 142 ms
23,888 KB
testcase_07 AC 168 ms
23,892 KB
testcase_08 AC 193 ms
23,892 KB
testcase_09 AC 323 ms
23,980 KB
testcase_10 AC 110 ms
23,904 KB
testcase_11 AC 122 ms
23,864 KB
testcase_12 AC 116 ms
23,848 KB
testcase_13 AC 213 ms
24,088 KB
testcase_14 AC 217 ms
23,884 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

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

#define ALL(obj) (obj).begin(),(obj).end()
#define SPEED cin.tie(0);ios::sync_with_stdio(false);

template<class T> using PQ = priority_queue<T>;
template<class T> using PQR = priority_queue<T,vector<T>,greater<T>>;

constexpr long long MOD = (long long)1e9 + 7;
constexpr long long MOD2 = 998244353;
constexpr long long HIGHINF = (long long)1e18;
constexpr long long LOWINF = (long long)1e15;
constexpr long double PI = 3.1415926535897932384626433L;

template <class T> vector<T> multivector(size_t N,T init){return vector<T>(N,init);}
template <class... T> auto multivector(size_t N,T... t){return vector<decltype(multivector(t...))>(N,multivector(t...));}
template <class T> void corner(bool flg, T hoge) {if (flg) {cout << hoge << endl; exit(0);}}
template <class T, class U>ostream &operator<<(ostream &o, const map<T, U>&obj) {o << "{"; for (auto &x : obj) o << " {" << x.first << " : " << x.second << "}" << ","; o << " }"; return o;}
template <class T>ostream &operator<<(ostream &o, const set<T>&obj) {o << "{"; for (auto itr = obj.begin(); itr != obj.end(); ++itr) o << (itr != obj.begin() ? ", " : "") << *itr; o << "}"; return o;}
template <class T>ostream &operator<<(ostream &o, const multiset<T>&obj) {o << "{"; for (auto itr = obj.begin(); itr != obj.end(); ++itr) o << (itr != obj.begin() ? ", " : "") << *itr; o << "}"; return o;}
template <class T>ostream &operator<<(ostream &o, const vector<T>&obj) {o << "{"; for (int i = 0; i < (int)obj.size(); ++i)o << (i > 0 ? ", " : "") << obj[i]; o << "}"; return o;}
template <class T, class U>ostream &operator<<(ostream &o, const pair<T, U>&obj) {o << "{" << obj.first << ", " << obj.second << "}"; return o;}
template <template <class tmp>  class T, class U> ostream &operator<<(ostream &o, const T<U> &obj) {o << "{"; for (auto itr = obj.begin(); itr != obj.end(); ++itr)o << (itr != obj.begin() ? ", " : "") << *itr; o << "}"; return o;}
void print(void) {cout << endl;}
template <class Head> void print(Head&& head) {cout << head;print();}
template <class Head, class... Tail> void print(Head&& head, Tail&&... tail) {cout << head << " ";print(forward<Tail>(tail)...);}
template <class T> void chmax(T& a, const T b){a=max(a,b);}
template <class T> void chmin(T& a, const T b){a=min(a,b);}
void YN(bool flg) {cout << (flg ? "YES" : "NO") << endl;}
void Yn(bool flg) {cout << (flg ? "Yes" : "No") << endl;}
void yn(bool flg) {cout << (flg ? "yes" : "no") << endl;}

/*
 * @title SegmentTreeBeats
 */
template<class T> class SegmentTreeBeats {
	T inf;
	size_t length;
	size_t height;
	vector<T>
	node_max_first,node_max_second,count_max_first,
	node_min_first,node_min_second,count_min_first,
	node_sum,lazy_add,lazy_update;
	vector<pair<int,int>> range;

	inline void internal_chmax(int k, long long x) {
		node_sum[k] += (x - node_max_first[k]) * count_max_first[k];
		if(node_max_first[k] == node_min_first[k]) node_max_first[k] = node_min_first[k] = x;
		else if(node_max_first[k] == node_min_second[k]) node_max_first[k] = node_min_second[k] = x;
		else node_max_first[k] = x;
		if(lazy_update[k] != inf && x < lazy_update[k]) lazy_update[k] = x;
	}
	inline void internal_chmin(int k, long long x) {
		node_sum[k] += (x - node_min_first[k]) * count_min_first[k];
		if(node_max_first[k] == node_min_first[k]) node_max_first[k] = node_min_first[k] = x;
		else if(node_max_second[k] == node_min_first[k]) node_min_first[k] = node_max_second[k] = x;
		else node_min_first[k] = x;
		if(lazy_update[k] != inf && lazy_update[k] < x) lazy_update[k] = x;
	}
	inline void internal_add(int k, long long x) {
		node_max_first[k] += x;
		if(node_max_second[k] != -inf) node_max_second[k] += x;
		node_min_first[k] += x;
		if(node_min_second[k] != inf) node_min_second[k] += x;
		node_sum[k] += x * (range[k].second - range[k].first);
		(lazy_update[k] != inf ? lazy_update[k]:lazy_add[k]) += x;
	}
	inline void internal_update(int k, long long x) {
		node_max_first[k] = x; node_max_second[k] = -inf;
		node_min_first[k] = x; node_min_second[k] = inf;
		count_max_first[k] = count_min_first[k] = (range[k].second - range[k].first);
		node_sum[k] = x * (range[k].second - range[k].first);
		lazy_update[k] = x;
		lazy_add[k] = 0;
	}
	inline void propagate(int k) {
		if(length-1 <= k) return;
		if(lazy_update[k] != inf) {
			internal_update(2*k+0, lazy_update[k]);
			internal_update(2*k+1, lazy_update[k]);
			lazy_update[k] = inf;
			return;
		}
		if(lazy_add[k] != 0) {
			internal_add(2*k+0, lazy_add[k]);
			internal_add(2*k+1, lazy_add[k]);
			lazy_add[k] = 0;
		}
		if(node_max_first[k] < node_max_first[2*k+0]) {
			internal_chmax(2*k+0, node_max_first[k]);
		}
		if(node_min_first[2*k+0] < node_min_first[k]) {
			internal_chmin(2*k+0, node_min_first[k]);
		}
		if(node_max_first[k] < node_max_first[2*k+1]) {
			internal_chmax(2*k+1, node_max_first[k]);
		}
		if(node_min_first[2*k+1] < node_min_first[k]) {
			internal_chmin(2*k+1, node_min_first[k]);
		}
	}
	inline void merge(int k) {
		node_sum[k] = node_sum[2*k+0] + node_sum[2*k+1];
		if(node_max_first[2*k+0] < node_max_first[2*k+1]) {
			node_max_first[k] = node_max_first[2*k+1];
			count_max_first[k] = count_max_first[2*k+1];
			node_max_second[k] = max(node_max_first[2*k+0], node_max_second[2*k+1]);
		}
		else if(node_max_first[2*k+0] > node_max_first[2*k+1]) {
			node_max_first[k] = node_max_first[2*k+0];
			count_max_first[k] = count_max_first[2*k+0];
			node_max_second[k] = max(node_max_second[2*k+0], node_max_first[2*k+1]);
		}
		else {
			node_max_first[k] = node_max_first[2*k+0];
			count_max_first[k] = count_max_first[2*k+0] + count_max_first[2*k+1];
			node_max_second[k] = max(node_max_second[2*k+0], node_max_second[2*k+1]);
		}
		if(node_min_first[2*k+0] < node_min_first[2*k+1]) {
			node_min_first[k] = node_min_first[2*k+0];
			count_min_first[k] = count_min_first[2*k+0];
			node_min_second[k] = min(node_min_second[2*k+0], node_min_first[2*k+1]);
		}
		else if(node_min_first[2*k+0] > node_min_first[2*k+1]) {
			node_min_first[k] = node_min_first[2*k+1];
			count_min_first[k] = count_min_first[2*k+1];
			node_min_second[k] = min(node_min_first[2*k+0], node_min_second[2*k+1]);
		}
		else {
			node_min_first[k] = node_min_first[2*k+0];
			count_min_first[k] = count_min_first[2*k+0] + count_min_first[2*k+1];
			node_min_second[k] = min(node_min_second[2*k+0], node_min_second[2*k+1]);
		}
	}
public:
	SegmentTreeBeats(const int num,const T inf = (1LL<<60)) {
		vector<T> a(num,0);
		*this = SegmentTreeBeats(a,inf);
	}
	SegmentTreeBeats(const vector<T>& a,const T inf = (1LL<<60)) : inf(inf){
		int num = a.size();
		for (length = 1,height = 0; length <= num; length *= 2, height++);
		node_max_first.resize(2*length);
		node_max_second.resize(2*length);
		count_max_first.resize(2*length);
		node_min_first.resize(2*length);
		node_min_second.resize(2*length);
		count_min_first.resize(2*length);
		node_sum.resize(2*length);
		range.resize(2*length);
		lazy_add.resize(2*length);
		lazy_update.resize(2*length);

		for(int i=0; i<2*length; ++i) lazy_add[i] = 0, lazy_update[i] = inf;
		for(int i = 0; i < length; ++i) range[i+length] = make_pair(i,i+1);
		for(int i = length - 1; i >= 0; --i) range[i] = make_pair(range[(i<<1)+0].first,range[(i<<1)+1].second);

		for(int i=0; i<num; ++i) {
			node_max_first[length+i] = node_min_first[length+i] = node_sum[length+i] = a[i];
			node_max_second[length+i] = -inf;
			node_min_second[length+i] = inf;
			count_max_first[length+i] = count_min_first[length+i] = 1;
		}
		for(int i=num; i<length; ++i) {
			node_max_first[length+i] = node_max_second[length+i] = -inf;
			node_min_first[length+i] = node_min_second[length+i] = inf;
			count_max_first[length+i] = count_min_first[length+i] = 0;
		}
		for(int i=length-1; i; --i) merge(i);
	}
	inline void range_chmin(int a, int b, long long x,int k = 1) {
		if(b <= range[k].first || range[k].second <= a || node_max_first[k] <= x) return;
		if(a <= range[k].first && range[k].second <= b && node_max_second[k] < x) {
			internal_chmax(k, x);
			return;
		}
		propagate(k);
		range_chmin(a, b, x, 2*k+0);
		range_chmin(a, b, x, 2*k+1);
		merge(k);
	}
	inline void range_chmax(int a, int b, long long x,int k = 1) {
		if(b <= range[k].first || range[k].second <= a || x <= node_min_first[k]) return;
		if(a <= range[k].first && range[k].second <= b && x < node_min_second[k]) {
			internal_chmin(k, x);
			return;
		}
		propagate(k);
		range_chmax(a, b, x, 2*k+0);
		range_chmax(a, b, x, 2*k+1);
		merge(k);
	}
	inline void range_add(int a, int b, long long x,int k = 1) {
		if(b <= range[k].first || range[k].second <= a) return;
		if(a <= range[k].first && range[k].second <= b) {
			internal_add(k, x);
			return;
		}
		propagate(k);
		range_add(a, b, x, 2*k+0);
		range_add(a, b, x, 2*k+1);
		merge(k);
	}
	inline void range_update(int a, int b, long long x,int k = 1) {
		if(b <= range[k].first || range[k].second <= a) return;
		if(a <= range[k].first && range[k].second <= b) {
			internal_update(k, x);
			return;
		}
		propagate(k);
		range_update(a, b, x, 2*k+0);
		range_update(a, b, x, 2*k+1);
		merge(k);
	}
	inline T get_max(int a, int b, int k = 1) {
		if(b <= range[k].first || range[k].second <= a) return -inf;
		if(a <= range[k].first && range[k].second <= b) return node_max_first[k];
		propagate(k);
		T vl = get_max(a, b, 2*k+0);
		T vr = get_max(a, b, 2*k+1);
		return max(vl, vr);
	}
	inline T get_min(int a, int b, int k = 1) {
		if(b <= range[k].first || range[k].second <= a) return inf;
		if(a <= range[k].first && range[k].second <= b) return node_min_first[k];
		propagate(k);
		T vl = get_min(a, b, 2*k+0);
		T vr = get_min(a, b, 2*k+1);
		return min(vl, vr);
	}
	inline T get_sum(int a, int b, int k=1) {
		if(b <= range[k].first || range[k].second <= a) return 0;
		if(a <= range[k].first && range[k].second <= b) return node_sum[k];
		propagate(k);
		T vl = get_sum(a, b, 2*k+0);
		T vr = get_sum(a, b, 2*k+1);
		return vl + vr;
	}
};

int main() {
    SPEED
    int N,M=20000; cin >> N;
    SegmentTreeBeats<ll> seg1(M),seg2(M),seg3(M),seg4(M);
    ll pre=0,sum=0;
    while(N--){
        int lx,ly,rx,ry;
        cin >> lx >> ly >> rx >> ry;
        seg1.range_chmax(0,rx,ry);
        seg2.range_chmax(0,rx,-ly);
        seg3.range_chmax(0,-lx,ry);
        seg4.range_chmax(0,-lx,-ly);
        sum=seg1.get_sum(0,M)+seg2.get_sum(0,M)+seg3.get_sum(0,M)+seg4.get_sum(0,M);
        cout << sum-pre << endl;
        pre=sum;
    }
    return 0;
}
0