[Hnoi2016]序列 莫队+st表+单调栈

本文通过一道具体题目详细解析了莫队算法的应用方法。介绍了如何使用莫队算法解决区间查询问题,包括维护不同子序列最小值之和的技术细节。文中还提供了完整的代码实现及思路说明。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Description
给定长度为n的序列:a1,a2,…,an,记为a[1:n]。类似地,a[l:r](1≤l≤r≤N)是指序列:al,al+1,…,ar-
1,ar。若1≤l≤s≤t≤r≤n,则称a[s:t]是a[l:r]的子序列。现在有q个询问,每个询问给定两个数l和r,1≤l≤r
≤n,求a[l:r]的不同子序列的最小值之和。例如,给定序列5,2,4,1,3,询问给定的两个数为1和3,那么a[1:3]有
6个子序列a[1:1],a[2:2],a[3:3],a[1:2],a[2:3],a[1:3],这6个子序列的最小值之和为5+2+4+2+2+2=17。


Sample Input
5 5
5 2 4 1 3
1 5
1 3
2 4
3 5
2 5


Sample Output
28
17
11
11
17


这题竟然是我莫队第一题。。。
其实很久之前就莫队思想,只是不想打,结果这道题想来想去只能想到莫队一种想法,就写了一下莫队。
我考虑维护一个sum1,一个sum2
sum1[i]表示1~i、2~i、3~i、…、i~i最小值的和。
sum2[i]就反过来搞。
我们考虑莫队右端点的移位,我们把区间的最小值求出来,位置设为hh,那么l~r、l+1~r…hh~r的最小值其实全部都是a[hh],那么hh往左的部分就OK了,那么hh往右的部分其实只用sum1[r]-sum[hh]就可求出。
怎么证明?
sum1[hh]范围是1~hh、2~hh、3~hh、…、hh~hh
sum1[r]范围是1~r、2~r、3~r、…、r~r
我们发现l~hh、l+1~hh…hh~hh和l~r、l+1~r…hh~r的最小值其实是一样的就是a[hh]。那么1~hh、2~hh…l-1~hh和1~r、2~r…l-1~r其实也是一样的,这个也很好想,没什么好说的。
往左移其实反过来就好了。
注意中间有一个求最小值的过程我们需要一个st表来维护。
那么我们怎么求sum1,sum2呢?
考虑a[i]所能造成的影响,若离他最近的比a[i]小的位置为qq,那么qq+1~i这一段最小值就是a[i],那么就可得到sum[i]=sum[qq]+(i-qq)*a[i]。
怎么求离这个点最近的比他小的数呢?这一个我们考虑用单调栈维护。
毕竟第一次莫队没打过模版就写了,WA了半天。。。


#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;
typedef long long LL;
int _min(int x, int y) {return x < y ? x : y;}

struct node {
    int l, belong, r, p;
} q[110000];
struct tt {
    int p, x;
} sta[110000]; int top;
int a[110000], f[110000][20], Log[110000];
LL sum1[110000], sum2[110000], pu[110000], ans;
int nowl, nowr;

int _min2(int x, int y) {return a[x] < a[y] ? x : y;}

bool cmp1(node a, node b) {
    if(a.belong == b.belong) return a.r < b.r;
    return a.belong < b.belong;
}

int query(int l, int r) {
    int len = Log[r - l + 1];
    return _min2(f[l][len], f[r - (1 << len) + 1][len]);
}

void p1(int l, int r, LL kk) {
    int hh = query(l, r);
    ans += (LL)(hh - l + 1) * (LL)a[hh] * kk;
    ans += (sum1[r] - sum1[hh]) * kk;
}

void p2(int l, int r, LL kk) {
    int hh = query(l, r);
    ans += (LL)(r - hh + 1) * (LL)a[hh] * kk;
    ans += (sum2[l] - sum2[hh]) * kk;
}

int main() {
    int n, m; scanf("%d%d", &n, &m); int kk = sqrt(n);
    Log[1] = 0;
    for(int i = 2; i <= n; i++) {
        if((1 << Log[i - 1] + 1) < i) Log[i] = Log[i - 1] + 1;
        else Log[i] = Log[i - 1];
    }
    for(int i = 1; i <= n; i++) scanf("%d", &a[i]), f[i][0] = i;
    for(int i = 1; i <= m; i++) {
        scanf("%d%d", &q[i].l, &q[i].r); q[i].p = i;
        q[i].belong = _min((q[i].l - 1) / kk + 1, kk + 1);
    }
    sort(q + 1, q + m + 1, cmp1);
    for(int j = 1; j <= 18; j++) {
        for(int i = 1; i + (1 << j - 1) <= n; i++) {
            f[i][j] = _min2(f[i][j - 1], f[i + (1 << j - 1)][j - 1]);
        }
    }
    sta[1].p = 1; sta[1].x = a[1]; top = 1; sum1[1] = a[1];
    for(int i = 2; i <= n; i++) {
        while(top && a[i] <= sta[top].x) top--;
        sum1[i] = sum1[sta[top].p] + (LL)a[i] * (i - sta[top].p);
        sta[++top].x = a[i]; sta[top].p = i;
    }
    sta[0].p = n + 1; sta[1].p = n; sta[1].x = a[n]; top = 1; sum2[n] = a[n];
    for(int i = n - 1; i >= 1; i--) {
        while(top && a[i] <= sta[top].x) top--;
        sum2[i] = sum2[sta[top].p] + (LL)a[i] * (sta[top].p - i);
        sta[++top].x = a[i]; sta[top].p = i;
    }
    ans = 0;
    nowl = 1; nowr = 0;
    for(int i = 1; i <= m; i++) {
        for(int j = nowr + 1; j <= q[i].r; j++) p1(nowl, j, 1);
        for(int j = q[i].r + 1; j <= nowr; j++) p1(nowl, j, -1);
        for(int j = nowl; j < q[i].l; j++) p2(j, q[i].r, -1);
        for(int j = q[i].l; j < nowl; j++) p2(j, q[i].r, 1);
        nowl = q[i].l, nowr = q[i].r;
        pu[q[i].p] = ans;
    }
    for(int i = 1; i <= m; i++) printf("%lld\n", pu[i]);
    return 0;
}
内容概要:本文深入解析了扣子COZE AI编程及其详细应用代码案例,旨在帮助读者理解新一代低门槛智能体开发范式。文章从五个维度展开:关键概念、核心技巧、典型应用场景、详细代码案例分析以及未来发展趋势。首先介绍了扣子COZE的核心概念,如Bot、Workflow、Plugin、Memory和Knowledge。接着分享了意图识别、函数调用链、动态Prompt、渐进式发布及监控可观测等核心技巧。然后列举了企业内部智能客服、电商导购助手、教育领域AI助教和金融行业合规质检等应用场景。最后,通过构建“会议纪要智能助手”的详细代码案例,展示了从需求描述、技术方案、Workflow节点拆解到调试与上线的全过程,并展望了多智能体协作、本地私有部署、Agent2Agent协议、边缘计算插件和实时RAG等未来发展方向。; 适合人群:对AI编程感兴趣的开发者,尤其是希望快速落地AI产品的技术人员。; 使用场景及目标:①学习如何使用扣子COZE构建生产级智能体;②掌握智能体实例、自动化流程、扩展能力和知识库的使用方法;③通过实际案例理解如何实现会议纪要智能助手的功能,包括触发器设置、下载节点、LLM节点Prompt设计、Code节点处理和邮件节点配置。; 阅读建议:本文不仅提供了理论知识,还包含了详细的代码案例,建议读者结合实际业务需求进行实践,逐步掌握扣子COZE的各项功能,并关注其未来的发展趋势。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值