社区讨论
线段树做法求助
P1440求m区间内的最小值参与者 8已保存回复 10
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 10 条
- 当前快照
- 1 份
- 快照标识符
- @mi6mjvmc
- 此快照首次捕获于
- 2025/11/20 07:19 4 个月前
- 此快照最后确认于
- 2025/11/20 07:19 4 个月前
CPP
#include <bits/stdc++.h>
#define ll int
using namespace std;
ll n, m;
ll L = 1, a[500100];
struct st
{
ll left, right;
ll lazy, s;
}t[500005];
inline int read()
{
int x=0, f = 1;
char ch=getchar();
while(ch > '9' || ch < '0')
{
if(ch=='-')
f=-1;
ch=getchar();
}
while(ch >= '0' && ch <= '9')
{
x *= 10;
x += (ch-'0');
ch = getchar();
}
return x * f;
}
inline void write(int x)
{
if(x < 0) putchar('-'), x = -x;
if(x > 9) write(x / 10);
putchar(x % 10 + '0');
}
void build_tree()
{
while(L < n) L *= 2;
for(ll i = 1; i <= n; i++)
t[i + L - 1].left = t[i + L - 1].right = i,
t[i + L - 1].s = a[i];
for(ll i = L + n;i < 2 * L;i++)
t[i].left = t[i].right = i - L + 1;
for(ll i = L - 1; i >= 1; i--)
t[i].left = t[2 * i].left,
t[i].right = t[2 * i + 1].right,
t[i].s = min(t[2 * i + 1].s, t[2 * i].s);
}
ll query(ll id, ll left, ll right)
{
if(t[id].left == left && t[id].right == right)
return t[id].s;
if(t[2 * id].right >= right) return query(2 * id, left, right);
else if(t[2 * id + 1].left <= left) return query(2 * id + 1, left, right);
else return min(query(2 * id, left, t[2 * id].right), query(2 * id + 1, t[2 * id + 1].left, right));
}
int main(int argc, char *argv[])
{
n = read();
m = read();
for(int i = 1; i <= n; i++) a[i] = read();
build_tree();
for(int i = 1; i <= n; i++)
{
if(i == 1) write(0);
else if(i <= m) write(query(1, 1, i - 1));
else if(i > m) write(query(1, i - m, i - 1));
printf("\n");
}
return 0;
}
CPP#2加了输入输出后卡过(900ms+),#10永远的TLE求大佬优化。
回复
共 10 条回复,欢迎继续交流。
正在加载回复...