Submission #893808

#TimeUsernameProblemLanguageResultExecution timeMemory
893808yfrank792Sjeckanje (COCI21_sjeckanje)C++14
110 / 110
487 ms36436 KiB
#include <bits/stdc++.h> using namespace std; typedef long long ll; typedef vector<int> vi; typedef vector<ll> vll; typedef pair<int,int> pii; typedef pair<ll,ll> pll; typedef queue<int> qi; typedef set<int> si; typedef priority_queue<int> pqi; typedef priority_queue<ll> pql; typedef priority_queue<int,vi,greater<int> > pqi_g; typedef priority_queue<ll,vll,greater<ll> > pql_g; #define F first #define S second #define PB push_back #define PF push_front #define MP make_pair #define FOR(i,a,b) for (int i=a; i<=b; i++) #define _FOR(i,a,b) for (int i=a; i>=b; i--) #define F0R(i,a,b,x) for (int i=a; i<=b; i+=x) #define FOR_(x,v) for (auto x : v) #define F0R_(x,v) for (auto &x : v) const int INF = 0x3f3f3f3f; const int maxn = 2e5+2; const ll MOD = 1e9+7; //? link: https://oj.uz/problem/view/COCI21_sjeckanje //? sol: segtree // - it can be observed that the segments that will produce the max total value are always either increasing or decreasing // - since the max total value is sum of the difference b/t the max and min values in each segment, we can store the array as one of differences // - this way, the value for a segment is just the sum of the differences in that segment // - when making updates, we then only need to change the end values of the segments that are affected // - we can then use a segtree to store the difference array // - since each segment must be one spaced apart (can't use the same element twice), we store the max value for each segtree node given 4 scenarios: // - take the left value and the right value // - take the left value and not the right value // - take the right value and not the left value // - take neither the left value nor the right value // - we also store the left and right border values for each node int n, q; class segtree { struct node {ll yy,yn,ny,nn,l,r;} d[4*maxn]; private: ll inline ls(ll x) {return x<<1;} ll inline rs(ll x) {return x<<1|1;} node inline op(node &l,node &r) { node ret = { max(l.yn+r.yy, l.yy+r.ny), // yy max(l.yy+r.nn, l.yn+r.yn), // yn max(l.ny+r.ny, l.nn+r.yy), // ny max(l.ny+r.nn, l.nn+r.yn), // nn l.l, // l r.r // r }; if ((l.r>=0 && r.l>=0) || (l.r<=0 && r.l<=0)) { ret.yy = max(ret.yy, l.yy+r.yy); ret.yn = max(ret.yn, l.yy+r.yn); ret.ny = max(ret.ny, l.ny+r.yy); ret.nn = max(ret.nn, l.ny+r.yn); } return ret; } public: ll a[maxn]; void init(ll s=1,ll t=n,ll p=1) { if (s==t) { d[p] = {abs(a[s]),0,0,0,a[s],a[s]}; return; } ll mid = s + ((t-s)>>1); init(s, mid, ls(p)); init(mid+1, t, rs(p)); d[p] = op(d[ls(p)], d[rs(p)]); } void upd(ll v,ll x,ll s=1,ll t=n,ll p=1) { // upd pos v by value x ~ p=cur pos, s,t=cur range if (s==t) { a[s] += x; d[p] = {abs(a[s]),0,0,0,a[s],a[s]}; return; } ll mid = s + ((t-s)>>1); if (v<=mid) upd(v,x,s,mid,ls(p)); else upd(v,x,mid+1,t,rs(p)); d[p] = op(d[ls(p)], d[rs(p)]); } ll query() { return max(d[1].yy, max(d[1].yn, max(d[1].ny, d[1].nn))); } void output_a() { FOR(i,1,n) cout << a[i] << " "; cout << endl; } } st; int main() { // faster cin/cout ios_base::sync_with_stdio(false); cin.tie(NULL); // freopen("c.in","r",stdin); cin >> n >> q; int last; cin>>last; st.a[1]=0; FOR(i,2,n) { int x; cin>>x; st.a[i] = x-last; last = x; } st.init(); FOR(_,1,q) { int l,r,x; cin>>l>>r>>x; if (l!=1) st.upd(l,x); if (r!=n) st.upd(r+1,-x); // st.output_a(); cout << st.query() << endl; } return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...