#include<bits/stdc++.h>
#define ll long long
using namespace std;
struct Zap{
ll l;
ll r;
ll u;
ll i;
};
struct Zm{
ll u;
int helpV;
ll i;
ll a;
ll b;
};
const int LOG = 18;
const int base = 1 << 18;
const ll INF = 1e9 + 1;
const int MAXN = 2e5 + 7;
ll A[MAXN];
ll B[MAXN];
ll dist[MAXN];
ll dl[MAXN];
ll dr[MAXN];
ll whr[MAXN];
ll w[MAXN];
pair<ll, ll> treeW[base * 2];
pair<ll, ll> treeM[base * 2];
Zm zm[MAXN*3];
ll ans[MAXN];
ll sparse[MAXN][LOG];
ll logg[MAXN];
pair<ll, ll> jump[MAXN][LOG];
Zap zapyt[MAXN];
stack<pair<ll, pair<ll, ll>>> mon;
inline pair<ll, ll> dodajP(pair<ll, ll> a, pair<ll, ll> b){
return {a.first+b.first, a.second+b.second};
}
pair<ll, ll> queryW(int w, int l, int r, int pocz, int kon){
if(r < pocz || kon < l){
return {0, 0};
}
else if(pocz <= l && r <= kon){
return treeW[w];
}
else{
int mid = (l+r)/2;
int left = w*2;
int right = w*2+1;
return dodajP(queryW(left, l, mid, pocz, kon), queryW(right, mid+1, r, pocz, kon));
}
}
void addW(int w, pair<ll, ll> val){
w += base-1;
treeW[w] = val;
w >>= 1;
while(w != 0){
treeW[w] = dodajP(treeW[w*2], treeW[w*2+1]);
w >>= 1;
}
}
pair<ll, ll> queryM(int w, int l, int r, int pocz, int kon){
if(r < pocz || kon < l){
return {INF, 0};
}
if(pocz <= l && r <= kon){
return treeM[w];
}
else{
int mid = (l+r)/2;
int left = w*2;
int right = w*2+1;
return min(queryM(left, l, mid, pocz, kon), queryM(right, mid+1, r, pocz, kon));
}
}
ll sparseRead(ll l, ll r){
ll d = (r-l+1);
ll k = logg[d];
return max(sparse[l][k], sparse[r-(1<<k)+1][k]);
}
bool compZm(Zm a, Zm b){
return (make_pair(a.u, a.helpV) < make_pair(b.u, b.helpV));
}
bool compZap(Zap a, Zap b){
return a.u < b.u;
}
int32_t main(){
for(int i = 0 ; i < LOG ; i++){
logg[(1 << i)] = i;
}
for(int i = 1 ; i <= MAXN ; i++){
logg[i] = max(logg[i-1], logg[i]);
}
int n, q;
cin >> n >> q;
for(int i = 1; i <= n ; i++){
cin >> A[i];
dist[i+1] = dist[i]+A[i];
sparse[i][0] = A[i];
}
for(int d = 1 ; d < LOG ; d++){
for(int i = 1; i <= n ; i++){
sparse[i][d] = max(sparse[i][d-1], sparse[min(n, i+(1 << (d-1)))][d-1]);
}
}
for(int i = 1; i <= n ; i++){
cin >> B[i];
}
B[n+1] = INF;
mon.push({0, {INF, -1}});
for(int i = 1 ; i <= n ; i++){
pair<ll, pair<ll, ll>> akt = {B[i], {dist[i], i}};
while(mon.top().first >= B[i]){
mon.pop();
}
// cerr << i << " " << B[i] << " " << mon.top().first << " " << mon.top().second.second << " z\n";
dl[i] = dist[i]-mon.top().second.first;
if(mon.top().second.second == -1){
dl[i] = INF;
}
mon.push(akt);
}
while(mon.top().first > 0){
mon.pop();
}
for(int i = n ; i > 0 ; i--){
pair<ll, pair<ll, ll>> akt = {B[i], {dist[i], i}};
while(mon.top().first > B[i]){
mon.pop();
}
dr[i] = mon.top().second.first-dist[i];
whr[i] = mon.top().second.second;
if(mon.top().second.second == -1){
dr[i] = INF;
whr[i] = n+1;
}
mon.push(akt);
}
for(int i = 1; i <= q ; i++){
cin >> zapyt[i].l >> zapyt[i].r >> zapyt[i].u;
zapyt[i].i = i;
}
ll zmit = 0;
for(int i = 1; i <= n+1 ; i++){
// w[i] = max(0LL, min(min(u, dl[i]), min(dr[i], dl[i]+dr[i]-u)));
if(i <= n){
int mn = min(dl[i], dr[i]);
int wk = max(dl[i], dr[i]);
zm[++zmit] = {mn, 0, i, 0, mn*B[i]};
zm[++zmit] = {wk, 1, i, -B[i], (dl[i]+dr[i])*B[i]};
zm[++zmit] = {dl[i]+dr[i], 1, i, 0, 0};
}
treeW[i+base-1] = {B[i], 0};
treeM[i+base-1] = {B[i], -i};
}
for(int i = base-1 ; i > 0 ; i--){
treeW[i] = dodajP(treeW[i*2],treeW[i*2+1]);
treeM[i] = min(treeM[i*2], treeM[i*2+1]);
}
whr[n+1] = n+1;
dr[n+1] = 0;
for(int i = 1; i <= n+1 ; i++){
ll nast = whr[i];
jump[i][0] = {whr[i], (dist[nast]-dist[i])*B[i]};
}
for(int d = 1 ; d < LOG ; d++){
for(int i = 1; i <= n+1 ; i++){
ll nk = jump[i][d-1].second+jump[jump[i][d-1].first][d-1].second;
jump[i][d] = {jump[jump[i][d-1].first][d-1].first, nk};
}
}
sort(zm+1, zm+1+zmit, compZm);
zmit = 1;
sort(zapyt+1, zapyt+1+q, compZap);
// for(int i = 1; i <= n ; i++){
// cerr << jump[i][0].first << " ";
// }cerr << "\n";
// for(int i = 1; i <= n ; i++){
// cerr << jump[i][1].first << " ";
// }cerr << "\n";
// for(int i = 1; i <= n ; i++){
// cerr << jump[i][2].first << " ";
// }cerr << "\n";
// for(int i = 1; i <= n ; i++){
// cerr << w[i] << " ";
// }cerr << "\n";
// for(int i = 1; i <= n ; i++){
// cerr << dl[i] << " ";
// }cerr << "\n";
// for(int i = 1; i <= n ; i++){
// cerr << dr[i] << " ";
// }cerr << "\n";
for(int ii = 1; ii <= q ; ii++){
ll i = zapyt[ii].i;
ll l = zapyt[ii].l;
ll r = zapyt[ii].r;
ll u = zapyt[ii].u;
if(sparseRead(l, r-1) > u){
ans[i] = -1;
continue;
}
int k = LOG-1;
ll gdz = l;
// cerr << gdz << " <<\n";
int limjp = min(u, dist[r]-dist[l]);
while(k >= 0){
if(dist[jump[gdz][k].first]-dist[l] <= limjp){ //
ans[i] += jump[gdz][k].second;
gdz = jump[gdz][k].first;
}
k--;
}
// cerr << ans[i] << " " << gdz << " przed prz\n";
if(gdz == r){
continue;
}
ans[i] += min(u, dr[gdz])*B[gdz];
gdz++;
// cerr << ans[i] << " " << gdz << " po prz\n";
auto it = lower_bound(dist+1, dist+1+(n+1), dist[r]-u);
ll whpoczfk = it-dist;
ll whminr = -queryM(1, 1, base, max(l, whpoczfk), r).second;
// cerr << whpoczfk << " " << whminr << " <<<\n";
if(/*dist[r]-dist[gdz] >= u*/gdz <= whminr){
while(zmit <= n*3 && zm[zmit].u < u){
addW(zm[zmit].i, {zm[zmit].a, zm[zmit].b});
zmit++;
}
// cerr << " faza srodkowa\n";
pair<ll, ll> afunkcja = queryW(1, 1, base, gdz, whminr);
ans[i] += afunkcja.first*u+afunkcja.second;
}
// faza koncowa
ans[i] -= min(u, dr[whminr])*B[whminr];
ans[i] += (dist[r]-dist[whminr])*B[whminr];
}
for(int i = 1; i <= q ; i++){
cout << ans[i] << "\n";
}
return 0;
}
Compilation message (stderr)
Main.cpp: In function 'int32_t main()':
Main.cpp:104:17: warning: iteration 200006 invokes undefined behavior [-Waggressive-loop-optimizations]
104 | logg[i] = max(logg[i-1], logg[i]);
| ~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~
Main.cpp:103:23: note: within this loop
103 | for(int i = 1 ; i <= MAXN ; i++){
| ~~^~~~~~~
# | 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... |