社区讨论
求调玄关,启发式+树状数组 TLE on #18 #19
P4755Beautiful Pair参与者 1已保存回复 1
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 1 条
- 当前快照
- 1 份
- 快照标识符
- @mhj3fwfw
- 此快照首次捕获于
- 2025/11/03 20:05 4 个月前
- 此快照最后确认于
- 2025/11/03 20:05 4 个月前
代码:
CPP#include <bits/stdc++.h>
#define PII pair <int, int>
#define LL long long
#define DB double
#define ST string
#define fr(x, y, z) for(int x = (y); x <= (z); x ++ )
#define dfr(x, y, z) for(int x = (y); x >= (z); x -- )
using namespace std;
const int N = 300010, INF = 1e9 + 7;
int T, n, k, a[N];
int fa[N][30], mx[N][30], _log[N];
int get(int x, int y)
{
int len = y - x + 1;
int Lmax = mx[x][_log[len]];
int Rmax = mx[y - (1 << _log[len]) + 1][_log[len]];
// printf("%d %d %d %d %d %d %d\n", x, y, len, _log[len], Lmax, Rmax, a[Lmax] > a[Rmax] ? Lmax : Rmax);
return a[Lmax] > a[Rmax] ? Lmax : Rmax;
}
int cnt;
vector <PII> v[N];
void work(int l, int r)
{
if(l > r) return ;
int p = get(l, r);
if(p - l < r - p)
{
dfr(i, p, l)
{
v[p - 1].push_back({a[p] / a[i], -1});
v[r].push_back({a[p] / a[i], 1});
// printf("%d -> [%d, %d](<= %d)\n", i, p, r, a[p] / a[i]);
}
}
else
{
fr(i, p, r)
{
v[l - 1].push_back({a[p] / a[i], -1});
v[p].push_back({a[p] / a[i], 1});
// printf("[%d, %d] -> %d(<= %d)\n", l, p, i, a[p] / a[i]);
}
}
// printf("[%d, %d] -> [%d, %d], [%d, %d]\n", l, r, l, p - 1, p + 1, r);
work(l, p - 1);
work(p + 1, r);
}
map <int, LL> t;
void insert(int x)
{ while(x < INF) t[x] ++ , x += (x & -x); }
int query(int x)
{
LL res = 0;
while(x) res += t[x], x -= (x & -x);
return res;
}
signed main()
{
scanf("%d", &n);
fr(i, 1, n) scanf("%d", &a[i]);
fr(i, 2, n) _log[i] = _log[i / 2] + 1;
// 维护 RMQ
fr(i, 0, n) fa[i][0] = i, mx[i][0] = i;
fr(j, 1, 20) fr(i, 1, n)
{
if(i + (1 << j) - 1 > n) { fa[i][j] = N; continue; }
fa[i][j] = fa[fa[i][j - 1] + 1][j - 1];
int l = mx[i][j - 1], r = mx[fa[i][j - 1] + 1][j - 1];
if(a[l] < a[r]) mx[i][j] = r;
else mx[i][j] = l;
}
work(1, n);
// memcpy(b, a, sizeof a);
// sort(b + 1, b + 1 + n);
// fr(i, 1, n) a[i] = lower_bound(b + 1, b + 1 + n, a[i]) - b;
// fr(i, 1, n) printf("%d%c", a[i], " \n"[i == n]);
LL res = 0;
fr(i, 1, n)
{
insert(a[i]);
for(PII j : v[i]) res += 1ll * query(j.first) * j.second;
}
printf("%lld\n", res);
return 0;
}
/*
2
5 3
2 3 2 2 5
10 4
1 5 4 3 6 2 10 8 4 5
*/
回复
共 1 条回复,欢迎继续交流。
正在加载回复...