#include<bits/stdc++.h>
using namespace std;
int rd() {
int res = 0;
bool fl = false;
char c = getchar();
while (c < 48 || c > 57) {
if (c == 45) fl = !fl;
c = getchar();
}
while (48 <= c && c <= 57) res = (res << 3) + (res << 1) + (c ^ 48), c = getchar();
if (fl) return -res;
return res;
}
void wr(int x) {
if (x < 0) putchar(45), x = -x;
if (x > 9) wr(x / 10);
putchar(x % 10 + 48);
}
const int maxn = 1e5 + 5;
const int maxm = 305;
const int inf = 1e6 + 5;
struct seg {
int l, r, id;
inline bool operator <(const seg &x) const {
return r < x.r;
}
};
bool cmp(seg x, seg y) {
return x.l < y.l;
}
struct node {
int l, r, v, tag;
};
int n, m, maxd, maxp, num;
int a[maxn];
seg b[maxm];
node t[maxn << 2];
multiset<seg> s;
int anss[maxm];
void push_up(int pos) {
t[pos].v = min(t[pos << 1].v, t[pos << 1 | 1].v);
}
void push_down(int pos) {
if (t[pos].tag) {
t[pos << 1].tag += t[pos].tag, t[pos << 1].v += t[pos].tag;
t[pos << 1 | 1].tag += t[pos].tag, t[pos << 1 | 1].v += t[pos].tag;
t[pos].tag = 0;
}
}
void build(int pos, int l, int r) {
t[pos].l = l, t[pos].r = r;
if (l == r) {
t[pos].v = a[l];
return;
}
int mid = l + r >> 1;
build(pos << 1, l, mid);
build(pos << 1 | 1, mid + 1, r);
push_up(pos);
}
void update(int pos, int l, int r, int k) {
if (l <= t[pos].l && t[pos].r <= r) {
t[pos].v += k;
t[pos].tag += k;
return;
}
push_down(pos);
if (l <= t[pos << 1].r) update(pos << 1, l, r, k);
if (r >= t[pos << 1 | 1].l) update(pos << 1 | 1, l, r, k);
push_up(pos);
}
int query(int pos, int l, int r) {
if (l <= t[pos].l && t[pos].r <= r) {
return t[pos].v;
}
push_down(pos);
int res = inf;
if (l <= t[pos << 1].r) res = min(res, query(pos << 1, l, r));
if (r >= t[pos << 1 | 1].l) res = min(res, query(pos << 1 | 1, l, r));
return res;
}
void read() {
n = rd(), m = rd();
for (int i = 1; i <= n; i ++) a[i] = rd();
for (int i = 1; i <= m; i ++) b[i].l = rd(), b[i].r = rd(), b[i].id = i;
}
void init() {
build(1, 1, n);
sort(b + 1, b + m + 1, cmp);
for (int i = 1; i <= m; i ++) update(1, b[i].l, b[i].r, -1);
}
void solve() {
for (int i = 1, pos = 1; i <= n; i ++) {
while (pos <= m && b[pos].l == i) update(1, b[pos].l, b[pos].r, 1), s.insert(b[pos]), pos ++;
// for (auto it: s) {
// wr(it.l), putchar(' ');
// wr(it.r), putchar(' ');
// putchar(' ');
// }
// putchar('\n');
while (!s.empty() && s.begin() -> r < i) update(1, s.begin() -> l, s.begin() -> r, -1), s.erase(s.begin());
int res = query(1, i, i) - query(1, 1, n);
if (maxd < res) maxd = res, maxp = i;
// for (auto it: s) {
// wr(it.l), putchar(' ');
// wr(it.r), putchar(' ');
// putchar(' ');
// }
// putchar('*');
// putchar('\n');
}
for (int i = 1; i <= m; i ++) if (maxp < b[i].l || b[i].r < maxp) num ++, anss[num] = b[i].id;
wr(maxd), putchar('\n');
wr(num), putchar('\n');
for (int i = 1; i <= num; i ++) wr(anss[i]), putchar(' ');
}
int main() {
read();
init();
solve();
}
此代码为正确代码,但是 multiset erase 部分不知为何不需要 * 取值而是留着指针