2023 rcpc
This commit is contained in:
289
2023/rcpc/d2/editorial/k-blabla-49.cpp
Normal file
289
2023/rcpc/d2/editorial/k-blabla-49.cpp
Normal file
@@ -0,0 +1,289 @@
|
||||
#include <bits/stdc++.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
#define int long long
|
||||
|
||||
int n,v[200005];
|
||||
int ans;
|
||||
|
||||
void solvell(int l,int r)///ambele in stanga
|
||||
{
|
||||
int mij = (l + r) / 2;
|
||||
int rmax = mij + 1;
|
||||
int maxst = 0,minst = 1e9;
|
||||
for (int i = mij; i >= l; i--)
|
||||
{
|
||||
maxst = max(maxst,v[i]);
|
||||
minst = min(minst,v[i]);
|
||||
while (rmax <= r and v[rmax] <= maxst and v[rmax] >= minst)
|
||||
rmax++;
|
||||
int topr = maxst - minst + i;
|
||||
int rreal = min(topr,rmax - 1);
|
||||
ans += max(0ll,rreal - mij);
|
||||
}
|
||||
}
|
||||
|
||||
void solverr(int l,int r)///ambele in dreapta
|
||||
{
|
||||
int mij = (l + r) / 2;
|
||||
int lmax = mij;
|
||||
int maxdr = 0,mindr = 1e9;
|
||||
for (int i = mij + 1; i <= r; i++)
|
||||
{
|
||||
maxdr = max(maxdr,v[i]);
|
||||
mindr = min(mindr,v[i]);
|
||||
while (lmax >= l and v[lmax] < maxdr and v[lmax] > mindr)
|
||||
lmax--;
|
||||
int topl = i - maxdr + mindr;
|
||||
int lreal = max(topl,lmax + 1);
|
||||
ans += max(0ll,mij - lreal + 1);
|
||||
}
|
||||
}
|
||||
|
||||
struct ura
|
||||
{
|
||||
int l,r,val;
|
||||
};
|
||||
|
||||
vector<ura>queries;
|
||||
|
||||
void addquery(int l,int r,int val)
|
||||
{
|
||||
ura aux;
|
||||
aux.l = l;
|
||||
aux.r = r;
|
||||
aux.val = val;
|
||||
queries.push_back(aux);
|
||||
}
|
||||
|
||||
int aib[200005];
|
||||
vector<pair<int,int>>updates;
|
||||
|
||||
void update(int pos,int val)
|
||||
{
|
||||
for (int i = pos; i <= n; i += (i & -i))
|
||||
aib[i] += val;
|
||||
}
|
||||
|
||||
int query(int pos)
|
||||
{
|
||||
int x = 0;
|
||||
for (int i = pos; i > 0; i -= (i & -i))
|
||||
x += aib[i];
|
||||
return x;
|
||||
}
|
||||
|
||||
void upd(int pos,int val)
|
||||
{
|
||||
updates.push_back({pos,val});
|
||||
update(pos,val);
|
||||
}
|
||||
|
||||
void resetaib()
|
||||
{
|
||||
for (auto it : updates)
|
||||
update(it.first,-it.second);
|
||||
updates.clear();
|
||||
}
|
||||
|
||||
bool cmp(ura A,ura B)
|
||||
{
|
||||
return A.val < B.val;
|
||||
}
|
||||
|
||||
void solvequeries(int l,int r)
|
||||
{
|
||||
sort(queries.begin(),queries.end(),cmp);
|
||||
vector<pair<int,int>>values;
|
||||
int mxx = 0;
|
||||
int mij = (l + r) / 2;
|
||||
for (int i = mij + 1; i <= r; i++)
|
||||
{
|
||||
mxx = max(mxx,v[i]);
|
||||
values.push_back({i - mxx,i});
|
||||
}
|
||||
sort(values.begin(),values.end());
|
||||
int i1 = 0;
|
||||
for (int i = 0; i < queries.size(); i++)
|
||||
{
|
||||
while (i1 < values.size() and values[i1].first <= queries[i].val)
|
||||
upd(values[i1].second,1ll),i1++;
|
||||
ans += query(queries[i].r) - query(queries[i].l - 1);
|
||||
}
|
||||
resetaib();
|
||||
}
|
||||
|
||||
void solvelr(int l,int r)///min in stanga,max in dreapta
|
||||
{
|
||||
int mij = (l + r) / 2;
|
||||
int maxst = 0,minst = 1e9;
|
||||
vector<int>premax(r - mij + 2);
|
||||
premax[1] = v[mij + 1];
|
||||
for (int i = mij + 2; i <= r; i++)
|
||||
premax[i - mij] = max(premax[i - mij - 1],v[i]);
|
||||
int rmin = mij + 1,rmax = mij + 1;///nu se poate r < rmin fiindca nu ar mai fi max in dreapta, nu se poate r >= rmax fiindca ar fi min in dreapta
|
||||
for (int i = mij; i >= l; i--)
|
||||
{
|
||||
maxst = max(maxst,v[i]);
|
||||
minst = min(minst,v[i]);
|
||||
while (rmin <= r and premax[rmin - mij] <= maxst)
|
||||
rmin++;
|
||||
while (rmax <= r and v[rmax] >= minst)
|
||||
rmax++;
|
||||
//if (l == 1 and r == 10)
|
||||
// cout << i << ' ' << rmin << ' ' << rmax << '\n';
|
||||
if (rmin <= rmax - 1)
|
||||
{
|
||||
///ma intreb cate valori intre rmin si rmax - 1 sunt valide
|
||||
///o valoare e valida daca r - maxpref[r] <= l - minst
|
||||
addquery(rmin,rmax - 1,i - minst);
|
||||
}
|
||||
}
|
||||
solvequeries(l,r);
|
||||
queries.clear();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
struct ura2
|
||||
{
|
||||
int l,r,val;
|
||||
};
|
||||
|
||||
vector<ura2>queries2;
|
||||
|
||||
void addquery2(int l,int r,int val)
|
||||
{
|
||||
ura2 aux;
|
||||
aux.l = l;
|
||||
aux.r = r;
|
||||
aux.val = val;
|
||||
queries2.push_back(aux);
|
||||
}
|
||||
|
||||
int aib2[200005];
|
||||
vector<pair<int,int>>updates2;
|
||||
|
||||
void update2(int pos,int val)
|
||||
{
|
||||
for (int i = pos; i <= 2 * n; i += (i & -i))
|
||||
aib2[i] += val;
|
||||
}
|
||||
|
||||
int query2(int pos)
|
||||
{
|
||||
int x = 0;
|
||||
for (int i = pos; i > 0; i -= (i & -i))
|
||||
x += aib2[i];
|
||||
return x;
|
||||
}
|
||||
|
||||
void upd2(int pos,int val)
|
||||
{
|
||||
updates2.push_back({pos,val});
|
||||
update2(pos,val);
|
||||
}
|
||||
|
||||
void resetaib2()
|
||||
{
|
||||
for (auto it : updates2)
|
||||
update2(it.first,-it.second);
|
||||
updates2.clear();
|
||||
}
|
||||
|
||||
bool cmp2(ura2 A, ura2 B)
|
||||
{
|
||||
return A.val < B.val;
|
||||
}
|
||||
|
||||
void solvequeries2(int l,int r)
|
||||
{
|
||||
sort(queries2.begin(),queries2.end(),cmp2);
|
||||
vector<pair<int,int>>values;
|
||||
int mij = (l + r) / 2;
|
||||
int mxx = 0;
|
||||
for (int i = mij; i >= l; i--)
|
||||
{
|
||||
mxx = max(mxx,v[i]);
|
||||
values.push_back({i + mxx,i});
|
||||
}
|
||||
sort(values.begin(),values.end());
|
||||
int i1 = 0;
|
||||
for (int i = 0; i < queries2.size(); i++)
|
||||
{
|
||||
while (i1 < values.size() and values[i1].first < queries2[i].val)
|
||||
upd2(values[i1].second,1),i1++;
|
||||
ans += (queries2[i].r - queries2[i].l + 1);
|
||||
ans -= (query2(queries2[i].r) - query2(queries2[i].l - 1));
|
||||
}
|
||||
resetaib2();
|
||||
}
|
||||
|
||||
void solverl(int l,int r)///min in dreapta,max in stanga
|
||||
{
|
||||
int mij = (l + r) / 2;
|
||||
int maxdr = 0,mindr = 1e9;
|
||||
vector<int>sufmax(mij - l + 2);
|
||||
sufmax[mij - l + 1] = v[mij];
|
||||
for (int i = mij - 1; i >= l; i--)
|
||||
sufmax[i - l + 1] = max(sufmax[i - l + 2],v[i]);
|
||||
int lmin = mij,lmax = mij;///nu se poate l > lmax fiindca nu ar mai fi max in stanga, nu se poate l <= lmin fiindca ar fi min in stanga
|
||||
for (int i = mij + 1; i <= r; i++)
|
||||
{
|
||||
maxdr = max(maxdr,v[i]);
|
||||
mindr = min(mindr,v[i]);
|
||||
while (lmax >= l and sufmax[lmax - l + 1] < maxdr)
|
||||
lmax--;
|
||||
while (lmin >= l and v[lmin] > mindr)
|
||||
lmin--;
|
||||
//if (l == 1 and r == 9)
|
||||
// cout << i << ' '<< lmin << ' ' << lmax << '\n';
|
||||
if (lmin + 1 <= lmax)
|
||||
{
|
||||
///ma intreb cate valori intre lmin + 1 si lmax sunt valide
|
||||
///o valoare e valida daca l + maxsuf[l] >= r + mindr
|
||||
addquery2(lmin + 1,lmax,i + mindr);
|
||||
}
|
||||
}
|
||||
solvequeries2(l,r);
|
||||
queries2.clear();
|
||||
}
|
||||
|
||||
void solve(int l,int r)
|
||||
{
|
||||
if (l > r)
|
||||
return;
|
||||
if (l == r)
|
||||
{
|
||||
ans++;
|
||||
return;
|
||||
}
|
||||
int mij = (l + r) / 2;
|
||||
solve(l,mij);
|
||||
solve(mij + 1,r);
|
||||
//cout << l << ' ' << r << ' ';
|
||||
solvell(l,r);
|
||||
//cout << ans - d1 << ' ';
|
||||
solverr(l,r);
|
||||
//cout << ans - d1 << ' ';
|
||||
solvelr(l,r);
|
||||
//cout << ans - d1 << ' ';
|
||||
solverl(l,r);
|
||||
//cout << ans - d1 << '\n';
|
||||
}
|
||||
|
||||
signed main()
|
||||
{
|
||||
ios_base::sync_with_stdio(false);
|
||||
cin.tie(NULL);
|
||||
cout.tie(NULL);
|
||||
cin >> n;
|
||||
for (int i = 1; i <= n; i++)
|
||||
cin >> v[i];
|
||||
solve(1,n);
|
||||
cout << ans;
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user