[JSOI2008] 最大数 (单调栈)
算法#
基础#
发现插入总在最后一个进行
单调栈维护一个区间的
单调队列维护以一个值为 的最大区间
显然可以使用单调栈维护
其原理为
当
那么显然
因此可以用单调栈维护一个包含
求解区间
优化#
二分 ( )#
显然可以二分查找
不加赘述
并查集 ( )#
对于一个下标
这样可以保证在插入的过程中仍然可以
#include <bits/stdc++.h>
const int MAXSIZE = 2e5 + 20;
#define int long long
int M, D;
class Union_Set
{
private:
public:
int fa[MAXSIZE];
int find(int Point)
{
return fa[Point] = (Point == fa[Point]) ? Point : find(fa[Point]);
}
void insert(int Fa, int Son)
{
fa[find(Son)] = find(Fa);
}
} US;
struct node
{
int Val;
int sub;
};
class MonoStack
{
private:
public:
node Val[MAXSIZE];
int top;
void init()
{
top = 0;
}
void insert(int x, int sub)
{
while (Val[top].Val < x && top)
{
US.insert(sub, Val[top].sub);
top--;
}
Val[++top].sub = sub;
Val[top].Val = x;
}
} MS;
int t = 0;
int size = 0;
int Num[MAXSIZE];
void solve()
{
MS.init();
while(M--)
{
char type;
std::cin >> type;
if(type == 'A')
{
scanf("%lld", &Num[++size]);
Num[size] = (Num[size] + t) % D;
US.fa[size] = size;
MS.insert(Num[size], size);
}else{
int L;
scanf("%lld", &L);
L = size - L + 1;
t = Num[US.find(L)];
printf("%lld\n", t);
}
}
}
signed main()
{
scanf("%lld %lld", &M, &D);
solve();
return 0;
}
总结#
代码#
注意在单调栈弹出是确保位置有意义
并查集插入时需要初始化
思路#
并查集往往可以用来处理连续的链向问题
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了