#include "weirdtree.h"
#include <bits/stdc++.h>
using namespace std;
#define sz(x) (int)x.size()
#define all(x) x.begin() , x.end()
const int N = 3e5 + 7;
const int inf = 1e9 + 7;
struct Node{
int maxcnt , max1 , max2 , chmin;
long long sum;
Node():maxcnt(0),max1(-inf),max2(-inf),sum(0),chmin(inf){}
} dumb;
Node merge(Node a , Node b){
Node c;
c.max1 = max(a.max1 , b.max1);
if(c.max1 == a.max1)c.maxcnt += a.maxcnt;
if(c.max1 == b.max1)c.maxcnt += b.maxcnt;
if(c.max1 != a.max1)c.max2 = max(c.max2 , a.max1);
if(c.max1 != a.max2)c.max2 = max(c.max2 , a.max2);
if(c.max1 != b.max1)c.max2 = max(c.max2 , b.max1);
if(c.max1 != b.max2)c.max2 = max(c.max2 , b.max2);
c.sum = a.sum + b.sum;
return c;
}
vector<Node> tree(4 * N);
void push(int ind , int l , int r){
if(tree[ind].chmin != inf){
// cout << "push0 : " << ind << " " << l << " " << r << endl;
// cout << "max1 : " << tree[ind].max1 << endl;
// cout << "max2 : " << tree[ind].max2 << endl;
// cout << "maxcnt : " << tree[ind].maxcnt << endl;
// cout << "chmin : " << tree[ind].chmin << endl;
if(tree[ind].chmin <= tree[ind].max1 and tree[ind].max2 < tree[ind].chmin){
tree[ind].sum -= 1LL * tree[ind].maxcnt * (tree[ind].max1 - tree[ind].chmin);
tree[ind].max1 = tree[ind].chmin;
if(l != r){
tree[ind*2].chmin = min(tree[ind*2].chmin , tree[ind].chmin);
tree[ind*2+1].chmin = min(tree[ind*2+1].chmin , tree[ind].chmin);
}
}
else if(tree[ind].chmin <= tree[ind].max2){
assert(l != r);
int mid = (l + r) / 2;
tree[ind*2].chmin = min(tree[ind*2].chmin , tree[ind].chmin);
push(ind*2 , l , mid);
tree[ind*2+1].chmin = min(tree[ind*2+1].chmin , tree[ind].chmin);
push(ind*2+1 , mid+1 , r);
tree[ind] = merge(tree[ind*2] , tree[ind*2+1]);
}
tree[ind].chmin = inf;
// cout << "push1" << endl;
}
}
Node query(int ql , int qr , int ind=1 , int l=0 , int r=N){
push(ind,l,r);
if(l >= ql and r <= qr){
return tree[ind];
}
else if(l > qr or r < ql){
return dumb;
}
int mid = (l + r) / 2;
return merge(query(ql,qr,ind*2,l,mid) , query(ql,qr,ind*2+1,mid+1,r));
}
void update_set(int qp , int qv , int ind=1 , int l=0 , int r=N){
push(ind,l,r);
if(l == r){
tree[ind].maxcnt = 1;
tree[ind].max1 = qv;
tree[ind].sum = qv;
tree[ind].max2 = -inf;
tree[ind].chmin = inf;
return;
}
int mid = (l + r) / 2;
if(qp <= mid)update_set(qp , qv , ind*2 , l , mid);
else update_set(qp , qv , ind*2+1 , mid+1 , r);
tree[ind] = merge(tree[ind*2] , tree[ind*2+1]);
}
void update_chmin(int ql , int qr , int qv , int ind=1 , int l=0 , int r=N){
push(ind,l,r);
if(l >= ql and r <= qr){
tree[ind].chmin = min(tree[ind].chmin , qv);
push(ind,l,r);
return;
}
else if(l > qr or r < ql)return;
int mid = (l + r) / 2;
update_chmin(ql , qr , qv , ind*2 , l , mid);
update_chmin(ql , qr , qv , ind*2+1 , mid+1 , r);
tree[ind] = merge(tree[ind*2] , tree[ind*2+1]);
}
void initialise(int N, int Q, int h[]) {
// cout << "flag0" << endl;
for(int i = 1;i<=N;i++){
update_set(i , h[i]);
}
// cout << "flag1" << endl;
}
void cut(int l, int r, int k) {
// cout << "BEFORE : ";for(int i = 1;i<=6;i++)cout << query(i,i).max1 << " ";cout << endl;
// cout << "flag2" << endl;
while(k){
// cout << "NEWCYCLE!!!" << endl;
// cout << "K : " << k << endl;
Node tmp = query(l,r);
if(tmp.max1 == 0)break;
// cout << "max1 : " << tmp.max1 << endl;
// cout << "max2 : " << tmp.max2 << endl;
// cout << "maxcnt : " << tmp.maxcnt << endl;
int steps = min(tmp.max1 - tmp.max2 , k / tmp.maxcnt);
// cout << "steps : " << steps << endl;
// cout << "flag2.1 : " << steps << endl;
if(steps){
// cout << "shave off" << endl;
update_chmin(l , r , tmp.max1 - steps);
k -= steps * tmp.maxcnt;
}
// cout << "K : " << k << endl;
// cout << "flag2.3" << endl;
if(steps != tmp.max1 - tmp.max2 and k % tmp.maxcnt){
// cout << "tirtikla : " << k % tmp.maxcnt << endl;
// cout << "TARGET : " << tmp.max1 - steps << endl;
int L = l , R = r;
while(L < R){
int MID = (L + R) / 2;
auto bro = query(L,MID);
// cout << "MID " << MID << " : " << bro.max1 << " , " << bro.maxcnt << endl;
if(bro.max1 != tmp.max1-steps or bro.maxcnt < k % tmp.maxcnt){
// cout << "FLAG0" << endl;
L = MID+1;
}
else {
// cout << "FLAG1" << endl;
R = MID;
}
}
// cout << "L : " << L << endl;
update_chmin(l , L , tmp.max1 - steps - 1);
k -= k % tmp.maxcnt;
}
// cout << "K : " << k << endl;
// cout << "flag2.4" << endl;
}
// cout << "flag3" << endl;
// cout << "AFTER : ";for(int i = 1;i<=6;i++)cout << query(i,i).max1 << " ";cout << endl;
}
void magic(int i, int x) {
update_set(i , x);
}
long long int inspect(int l, int r) {
return query(l,r).sum;
}
| # | 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... |
| # | Verdict | Execution time | Memory | Grader output |
|---|
| Fetching results... |
| # | Verdict | Execution time | Memory | Grader output |
|---|
| Fetching results... |
| # | Verdict | Execution time | Memory | Grader output |
|---|
| Fetching results... |