

#include <iostream>
#include <algorithm>
#define N 200005
#define ll long long
using namespace std;
int n;
ll a[N], b[N], c[N], h[N];
ll sum(int i, ll *ar) {
ll ret = 0;
while (i > 0) {
ret += ar[i];
i -= i&-i;
}
return ret;
}
ll query(int l, int r, ll *ar) {
return sum(r, ar) - sum(l-1, ar);
}
void update(int i, ll x, ll *ar) {
while (i <= n) {
ar[i] += x;
i += i&-i;
}
}
int main(void) {
ios::sync_with_stdio(false);
cin.tie(0);
int x;
cin>>n;
for (int i=1; i<=n; i++)
cin>>x, h[x] = i;
for (int i=1; i<=n; i++)
cin>>x, a[i] = h[x];
ll ans = 0;
for (int i=1; i<=n; i++) {
update(a[i], a[i], b);
update(a[i], 1, c);
ans += a[i]*query(1, a[i]-1, c) - query(1, a[i]-1, b);
}
cout<<ans<<'\n';
return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define int ll
class SparseTable
{
private:
std::vector<std::vector<int>> mx, mi;
std::vector<int> logTable;
public:
// 使用数组 arr 构造 ST 表
SparseTable(const std::vector<int> &arr)
{
int n = arr.size();
int maxLog = std::log2(n) + 1;
mx.assign(n, std::vector<int>(maxLog));
mi.assign(n, std::vector<int>(maxLog));
logTable.assign(n + 1, 0);
// 预处理对数表
for (int i = 2; i <= n; i++)
{
logTable[i] = logTable[i / 2] + 1;
}
// 初始化 ST 表
for (int i = 0; i < n; i++)
{
mx[i][0] = arr[i];
mi[i][0] = arr[i];
}
// 动态规划填充表
for (int j = 1; (1 << j) <= n; j++)
{
for (int i = 0; i + (1 << j) <= n; i++)
{
mx[i][j] = std::max(mx[i][j - 1], mx[i + (1 << (j - 1))][j - 1]);
mi[i][j] = std::min(mi[i][j - 1], mi[i + (1 << (j - 1))][j - 1]);
}
}
}
// 查询区间 [l, r] 的最大值
int querymax(int l, int r)
{
int j = logTable[r - l + 1];
return std::max(mx[l][j], mx[r - (1 << j) + 1][j]);
}
// 查询区间 [l, r] 的最小值
int querymin(int l, int r)
{
int j = logTable[r - l + 1];
return std::min(mi[l][j], mi[r - (1 << j) + 1][j]);
}
};
void solve()
{
int n, q;
cin >> n >> q;
vector<ll> v(n + 1);
for (int i = 1; i <= n; ++i)
{
cin >> v[i];
v[i] += v[i - 1];
}
SparseTable st(v);
for (int i = 0; i < q; ++i)
{
int a, b, c, d;
cin >> a >> b >> c >> d;
ll ans = 0;
if (b < c)
{
ans += v[c - 1] - v[b];
}
ll lv = v[b] - st.querymin(a - 1, b - 1);
ll rv = st.querymax(c, d) - v[c - 1];
cout << (ans + lv + rv) << '\n';
}
}
signed main()
{
ios_base ::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cout << setiosflags(ios::fixed) << setprecision(2);
int t = 1;
while (t--)
{
solve();
}
return 0;
}


#include <iostream>
using namespace std;
int a[1000005];
struct node {
int val, num, lazy;
} tree[4000005];
void pushup(node &n, node &n1, node &n2) {
if (n2.val <= n1.val) {
n.val = n2.val;
n.num = n2.num;
} else {
n.val = n1.val;
n.num = n1.num;
}
}
void build(int l, int r, int rt) {
tree[rt].lazy = -1;
if (l == r) {
tree[rt].val = a[l];
tree[rt].num = l;
return;
}
int m = (l+r)/2;
build(l, m, rt*2);
build(m+1, r, rt*2+1);
pushup(tree[rt], tree[rt*2], tree[rt*2+1]);
}
void pushdown(node &n, node &n1, node &n2) {
n1.val = max(n1.val-n.lazy, 0);
if (n1.lazy == -1)
n1.lazy = n.lazy;
else
n1.lazy += n.lazy;
n2.val = max(n2.val-n.lazy, 0);
if (n2.lazy == -1)
n2.lazy = n.lazy;
else
n2.lazy += n.lazy;
n.lazy = -1;
}
// 区间更新
void update(int L, int R, int C, int l, int r, int rt) {
if (L <= l && R >= r) {
tree[rt].val = max(tree[rt].val-C, 0);
if (tree[rt].lazy == -1)
tree[rt].lazy = C;
else
tree[rt].lazy += C;
return;
}
int m = (l+r)/2;
if (tree[rt].lazy != -1)
pushdown(tree[rt], tree[rt*2], tree[rt*2+1]);
if (L <= m)
update(L, R, C, l, m, rt*2);
if (R > m)
update(L, R, C, m+1, r, rt*2+1);
pushup(tree[rt], tree[rt*2], tree[rt*2+1]);
}
// 区间查询
node query(int L, int R, int l, int r, int rt) {
if (L <= l && R >= r)
return tree[rt];
int m = (l+r)/2;
if (tree[rt].lazy != -1)
pushdown(tree[rt], tree[rt*2], tree[rt*2+1]);
node n, n1{}, n2{};
if (L <= m)
n1 = query(L, R, l, m, rt*2);
if (R > m)
n2 = query(L, R, m+1, r, rt*2+1);
if (n1.num == 0)
return n2;
if (n2.num == 0)
return n1;
pushup(n, n1, n2);
return n;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n,k;
cin>>n>>k;
long long sum = 0;
for (int i=1; i<=n; i++)
cin>>a[i], sum += a[i];
build(1,n,1);
long long cnt = 0;
int i = 1;
while (i+k-1 <= n) {
node n0 = query(i, i+k-1, 1,n,1);
cnt += n0.val;
update(i, i+k-1, n0.val, 1,n,1);
i = n0.num+1;
}
cout<<sum - cnt*k + cnt<<'\n';
return 0;
}
903

被折叠的 条评论
为什么被折叠?



