結果
問題 | No.1074 増殖 |
ユーザー |
![]() |
提出日時 | 2020-06-05 23:55:04 |
言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 161 ms / 2,000 ms |
コード長 | 7,453 bytes |
コンパイル時間 | 2,224 ms |
コンパイル使用メモリ | 179,920 KB |
実行使用メモリ | 28,228 KB |
最終ジャッジ日時 | 2024-12-17 19:16:01 |
合計ジャッジ時間 | 3,746 ms |
ジャッジサーバーID (参考情報) |
judge1 / judge3 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 3 |
other | AC * 12 |
ソースコード
#include<bits/stdc++.h>using namespace std;typedef long long ll;template<typename T1,typename T2> bool chmin(T1 &a,T2 b){if(a<=b)return 0; a=b; return 1;}template<typename T1,typename T2> bool chmax(T1 &a,T2 b){if(a>=b)return 0; a=b; return 1;}int dx[4]={0,1,0,-1}, dy[4]={1,0,-1,0};long double eps = 1e-9;long double pi = acos(-1);#define N 40003class SegmentTree {const ll inf = 1e18;int n, n0;ll max_v[4*N], smax_v[4*N], max_c[4*N];ll min_v[4*N], smin_v[4*N], min_c[4*N];ll sum[4*N];ll len[4*N], ladd[4*N], lval[4*N];void update_node_max(int k, ll x) {sum[k] += (x - max_v[k]) * max_c[k];if(max_v[k] == min_v[k]) {max_v[k] = min_v[k] = x;} else if(max_v[k] == smin_v[k]) {max_v[k] = smin_v[k] = x;} else {max_v[k] = x;}if(lval[k] != inf && x < lval[k]) {lval[k] = x;}}void update_node_min(int k, ll x) {sum[k] += (x - min_v[k]) * min_c[k];if(max_v[k] == min_v[k]) {max_v[k] = min_v[k] = x;} else if(smax_v[k] == min_v[k]) {min_v[k] = smax_v[k] = x;} else {min_v[k] = x;}if(lval[k] != inf && lval[k] < x) {lval[k] = x;}}void push(int k) {if(n0-1 <= k) return;if(lval[k] != inf) {updateall(2*k+1, lval[k]);updateall(2*k+2, lval[k]);lval[k] = inf;return;}if(ladd[k] != 0) {addall(2*k+1, ladd[k]);addall(2*k+2, ladd[k]);ladd[k] = 0;}if(max_v[k] < max_v[2*k+1]) {update_node_max(2*k+1, max_v[k]);}if(min_v[2*k+1] < min_v[k]) {update_node_min(2*k+1, min_v[k]);}if(max_v[k] < max_v[2*k+2]) {update_node_max(2*k+2, max_v[k]);}if(min_v[2*k+2] < min_v[k]) {update_node_min(2*k+2, min_v[k]);}}void update(int k) {sum[k] = sum[2*k+1] + sum[2*k+2];if(max_v[2*k+1] < max_v[2*k+2]) {max_v[k] = max_v[2*k+2];max_c[k] = max_c[2*k+2];smax_v[k] = max(max_v[2*k+1], smax_v[2*k+2]);} else if(max_v[2*k+1] > max_v[2*k+2]) {max_v[k] = max_v[2*k+1];max_c[k] = max_c[2*k+1];smax_v[k] = max(smax_v[2*k+1], max_v[2*k+2]);} else {max_v[k] = max_v[2*k+1];max_c[k] = max_c[2*k+1] + max_c[2*k+2];smax_v[k] = max(smax_v[2*k+1], smax_v[2*k+2]);}if(min_v[2*k+1] < min_v[2*k+2]) {min_v[k] = min_v[2*k+1];min_c[k] = min_c[2*k+1];smin_v[k] = min(smin_v[2*k+1], min_v[2*k+2]);} else if(min_v[2*k+1] > min_v[2*k+2]) {min_v[k] = min_v[2*k+2];min_c[k] = min_c[2*k+2];smin_v[k] = min(min_v[2*k+1], smin_v[2*k+2]);} else {min_v[k] = min_v[2*k+1];min_c[k] = min_c[2*k+1] + min_c[2*k+2];smin_v[k] = min(smin_v[2*k+1], smin_v[2*k+2]);}}void _update_min(ll x, int a, int b, int k, int l, int r) {if(b <= l || r <= a || max_v[k] <= x) {return;}if(a <= l && r <= b && smax_v[k] < x) {update_node_max(k, x);return;}push(k);_update_min(x, a, b, 2*k+1, l, (l+r)/2);_update_min(x, a, b, 2*k+2, (l+r)/2, r);update(k);}void _update_max(ll x, int a, int b, int k, int l, int r) {if(b <= l || r <= a || x <= min_v[k]) {return;}if(a <= l && r <= b && x < smin_v[k]) {update_node_min(k, x);return;}push(k);_update_max(x, a, b, 2*k+1, l, (l+r)/2);_update_max(x, a, b, 2*k+2, (l+r)/2, r);update(k);}void addall(int k, ll x) {max_v[k] += x;if(smax_v[k] != -inf) smax_v[k] += x;min_v[k] += x;if(smin_v[k] != inf) smin_v[k] += x;sum[k] += len[k] * x;if(lval[k] != inf) {lval[k] += x;} else {ladd[k] += x;}}void updateall(int k, ll x) {max_v[k] = x; smax_v[k] = -inf;min_v[k] = x; smin_v[k] = inf;max_c[k] = min_c[k] = len[k];sum[k] = x * len[k];lval[k] = x; ladd[k] = 0;}void _add_val(ll x, int a, int b, int k, int l, int r) {if(b <= l || r <= a) {return;}if(a <= l && r <= b) {addall(k, x);return;}push(k);_add_val(x, a, b, 2*k+1, l, (l+r)/2);_add_val(x, a, b, 2*k+2, (l+r)/2, r);update(k);}void _update_val(ll x, int a, int b, int k, int l, int r) {if(b <= l || r <= a) {return;}if(a <= l && r <= b) {updateall(k, x);return;}push(k);_update_val(x, a, b, 2*k+1, l, (l+r)/2);_update_val(x, a, b, 2*k+2, (l+r)/2, r);update(k);}ll _query_max(int a, int b, int k, int l, int r) {if(b <= l || r <= a) {return -inf;}if(a <= l && r <= b) {return max_v[k];}push(k);ll lv = _query_max(a, b, 2*k+1, l, (l+r)/2);ll rv = _query_max(a, b, 2*k+2, (l+r)/2, r);return max(lv, rv);}ll _query_min(int a, int b, int k, int l, int r) {if(b <= l || r <= a) {return inf;}if(a <= l && r <= b) {return min_v[k];}push(k);ll lv = _query_min(a, b, 2*k+1, l, (l+r)/2);ll rv = _query_min(a, b, 2*k+2, (l+r)/2, r);return min(lv, rv);}ll _query_sum(int a, int b, int k, int l, int r) {if(b <= l || r <= a) {return 0;}if(a <= l && r <= b) {return sum[k];}push(k);ll lv = _query_sum(a, b, 2*k+1, l, (l+r)/2);ll rv = _query_sum(a, b, 2*k+2, (l+r)/2, r);return lv + rv;}public:SegmentTree(int n) {SegmentTree(n, nullptr);}SegmentTree(int n, ll *a) : n(n) {n0 = 1;while(n0 < n) n0 <<= 1;for(int i=0; i<2*n0; ++i) ladd[i] = 0, lval[i] = inf;len[0] = n0;for(int i=0; i<n0-1; ++i) len[2*i+1] = len[2*i+2] = (len[i] >> 1);for(int i=0; i<n; ++i) {max_v[n0-1+i] = min_v[n0-1+i] = sum[n0-1+i] = (a != nullptr ? a[i] : 0);smax_v[n0-1+i] = -inf;smin_v[n0-1+i] = inf;max_c[n0-1+i] = min_c[n0-1+i] = 1;}for(int i=n; i<n0; ++i) {max_v[n0-1+i] = smax_v[n0-1+i] = -inf;min_v[n0-1+i] = smin_v[n0-1+i] = inf;max_c[n0-1+i] = min_c[n0-1+i] = 0;}for(int i=n0-2; i>=0; i--) {update(i);}}// range minimize queryvoid update_min(int a, int b, ll x) {_update_min(x, a, b, 0, 0, n0);}// range maximize queryvoid update_max(int a, int b, ll x) {_update_max(x, a, b, 0, 0, n0);}// range add queryvoid add_val(int a, int b, ll x) {_add_val(x, a, b, 0, 0, n0);}// range update queryvoid update_val(int a, int b, ll x) {_update_val(x, a, b, 0, 0, n0);}// range minimum queryll query_max(int a, int b) {return _query_max(a, b, 0, 0, n0);}// range maximum queryll query_min(int a, int b) {return _query_min(a, b, 0, 0, n0);}// range sum queryll query_sum(int a, int b) {return _query_sum(a, b, 0, 0, n0);}};SegmentTree seg1(40004,0),seg2(40004,0);signed main(){ios::sync_with_stdio(false);cin.tie(0);cout << fixed << setprecision(20);int n;cin>>n;ll now = 0;int st = 20000;for(int i=0;i<n;i++){int a,b,c,d;cin>>a>>b>>c>>d;seg1.update_max(a+st,c+st,d);seg2.update_max(a+st,c+st,-b);ll ans = seg1.query_sum(0,40001) + seg2.query_sum(0,40001);cout << ans - now << "\n";//cerr << i << " " << seg1.get(0,40004) << " " << seg2.get(0,40004) << endl;now = ans;}}