#pragma region//
#include<bits/stdc++.h>
#define int long long
#pragma GCC optimize("Ofast,unroll-loops,no-stack-protector,fast-math")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#pragma comment(linker, "/stack:200000000")
#define f2(i, m) for(int i=0; i<m; i++)
#define f21(i, m) for(int i=1; i<m; i++)
#define f3(i, n, m) for(int i=n; i<m; i++)
#define f2_(i, m) for(int i=m; i>-1; i--)
#define f21_(i, m) for(int i=m; i>0; i--)
#define f3_(i, n, m) for(int i=n; i>=m; i--)
#define travG(idx) for(int i : g[idx])
#define travG_(i, idx) for(int i : g[idx])
#define trav(loop) for(int i : loop)
#define trav_(i, loop) for(int i : loop)
#define trav2(loop, idx) for(int i : loop[idx])
#define trav2_(i, loop, idx) for(int i : loop[idx])
#define ll long long
#define bs bitset
#define pii pair<int, int>
#define vi vector<int>
#define vvi vector<vector<int>>
#define ve vector<element>
#define ve_ vector<element_>
#define vpii vector<pair<int, int>>
#define qi queue<int>
#define qe queue<element>
#define qpii queue<pair<int, int>>
#define si stack<int>
#define se stack<element>
#define spii stack<pair<int, int>>
#define vb vector<bool>
#define pqi priority_queue<int>
#define pqi_ priority_queue<int, vi, greater<int>>
#define pqpii priority_queue<pair<int, int>>
#define pqpii_ priority_queue<pair<int, int>, vpii, greater<pii>>
#define pb push_back
#define pf push_front
#define pob pop_back()
#define pof pop_front()
#define len length()
#define elif else if
#define mod 1000000007
#pragma endregion
//#define debug
/*
#ifdef debug
#endif
#ifndef debug
#endif
*/
using namespace std;
constexpr bool debug = 0;
constexpr int mxn=5e5+1, mxq=5e5+1;
int n, q, c[mxn];
vi cor[mxn];
struct SEG
{
int curL;
// a + b -> maintain by vpii{a+b, l}
vpii ab;
// a + b + c
/*
function:
range query max
range update add
*/
vector<int> tree, tag;
int qu(int idx, int l, int r, int ql, int qr)
{
if(ql>r || qr<l) return 0;
if(ql<=l && r<=qr) return tree[idx];
{ // lazy transfer
tag[idx<<1]+=tag[idx], tag[idx<<1|1]+=tag[idx];
tree[idx<<1]+=tag[idx], tree[idx<<1|1]+=tag[idx], tag[idx]=0;
}
int m = l+r>>1;
return max(qu(idx<<1, l, m, ql, qr), qu(idx<<1|1, m+1, r, ql, qr));
}
void build(int idx, int l, int r)
{
if(l==r)
{
tree[idx]=c[l];
return;
}
int m = l+r>>1;
build(idx<<1, l, m), build(idx<<1|1, m+1, r);
tree[idx] = max(tree[idx<<1], tree[idx<<1|1]);
}
void ud(int idx, int l, int r, int ql, int qr, int v)
{
if(ql>r || qr<l) return;
if(ql<=l && r<=qr)
{
tree[idx]+=v;
tag[idx]+=v;
return;
}
{ // lazy transfer
tag[idx<<1]+=tag[idx], tag[idx<<1|1]+=tag[idx];
tree[idx<<1]+=tag[idx], tree[idx<<1|1]+=tag[idx], tag[idx]=0;
}
int m = l+r>>1;
ud(idx<<1, l, m, ql, qr, v), ud(idx<<1|1, m+1, r, ql, qr, v);
tree[idx] = max(tree[idx<<1], tree[idx<<1|1]);
}
void init_L(int l)
{
f3_(i, curL, l)
{
for(int j : cor[i])
{
// for each element in range [2j-i, n-1] can be updated
if((j<<1)-i>=n) continue; // out of array
if(debug)
{
cout<<"init: "<<i<<' '<<j<<'\n';
}
int value = c[i]+c[j];
auto rPtr = upper_bound(begin(ab), end(ab), pii{value, 0});
if(rPtr->second<(j<<1)-i && rPtr!=end(ab)) // needless to be updated
continue;
int r = (rPtr==end(ab) ? n-1 : rPtr->second-1);
while(1)
{
rPtr--;
ud(1, 0, n-1, max(rPtr->second, (j<<1)-i), r, value-rPtr->first);
r = rPtr->second-1;
if(r>=(j<<1)-i-1)
{
ab.erase(rPtr);
if(r==(j<<1)-i-1) break;
}
else break;
}
ab.insert(rPtr+1, {value, (j<<1)-i});
if(debug)
{
cout << "\n\n";
for(auto i : ab) cout << '{'<<i.first << ", " << i.second << "} ";
cout << "\n\n";
}
}
}
curL = l-1;
}
void init()
{
ab.pb({0, 0});
tree.resize(n<<2);
tag.resize(n<<2);
build(1, 0, n-1);
curL = n-1;
}
}seg;
signed main()// https://oj.uz/problem/view/IOI08_printer
{ ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
// input
{
si stk;
int tmp[mxn];
cin >> n;
f2(i, n)
{
int t; cin>>t;
c[i] = t;
while(!stk.empty() && c[i]>c[stk.top()])
stk.pop();
tmp[i] = stk.empty()?-1:stk.top();
stk.push(i);
if(i!=n-1) cor[i].pb(i+1);
}
while(!stk.empty()) stk.pop();
f2_(i, n-1)
{
if(tmp[i]==-1)
{
stk.push(i);
continue;
}
while(!stk.empty() && c[i]>c[stk.top()])
stk.pop();
if(stk.empty())
{
stk.push(i);
continue;
}
cor[tmp[i]].pb(stk.top());
if(debug)
{
cout<<tmp[i]<<' '<<stk.top()<<'\n';
}
stk.push(i);
}
}
// query and output
{
cin >> q;
struct output
{
int l, r, idx;
};
output query[q];
int ans[q];
int t=0;
for(output &i : query) cin>>i.l>>i.r, i.idx=t++;
sort(query, query+q, [&](output a, output b)
{
return a.l>b.l;
});
seg.init();
for(output i : query)
{
seg.init_L(i.l-1);
ans[i.idx] = seg.qu(1, 0, n-1, i.l+1, i.r-1);
}
for(int i:ans) cout<<i<<'\n';
}
return 0;
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |