2023 rcpc

This commit is contained in:
2024-04-22 16:45:09 +03:00
parent a0ddb657b7
commit 156202ada0
61 changed files with 4462 additions and 0 deletions

View 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;
}