1. 程式人生 > >【題解】NOI2016序列

【題解】NOI2016序列

hellip 最大化 min 多次 else truct code name bool

  Two - pointer 第一題…… 大概就是對於一段連續的區間求解,使用兩個指針不斷卡區間的長度直到區間不滿足條件吧。

  這題只要對區間以長度從小到大排一下序,然後使用兩個指針指向區間。線段樹維護被覆蓋最多次數的節點被覆蓋了多少次。如果滿足條件,由於我們是在第一次判斷的時候發現它滿足條件的,所以最後加入的這個區間一定對於答案產生了貢獻,也就是最大的區間。要使最小區間最大化,我們只需讓前面的指針慢慢往後跳直到不符合條件即可。

#include <bits/stdc++.h>
using namespace std;
#define maxn 5000000
#define
INF 999999999 int n, m, tot, cnt, b[maxn]; int ans = INF, num[maxn]; int mark[maxn]; map <int, int> Map; int read() { int x = 0, k = 1; char c; c = getchar(); while(c < 0 || c > 9) { if(c == -) k = -1; c = getchar(); } while(c >= 0 && c <=
9) x = x * 10 + c - 0, c = getchar(); return x * k; } struct node { int l, r, len; friend bool operator <(const node& a, const node& b) { if(a.len != b.len) return a.len < b.len; else if(a.l != b.l) return a.l < b.l; else return
a.r < b.r; } }A[maxn]; void push_down(int p) { if(!mark[p]) return; num[p << 1] += mark[p], num[p << 1 | 1] += mark[p]; mark[p << 1] += mark[p]; mark[p << 1 | 1] += mark[p]; mark[p] = 0; } void update(int p, int l, int r, int L, int R, int x) { if(L <= l && R >= r) { num[p] += x; mark[p] += x; return; } if(L > r || R < l) return; push_down(p); int mid = (l + r) >> 1; update(p << 1, l, mid, L, R, x), update(p << 1 | 1, mid + 1, r, L, R, x); num[p] = max(num[p << 1], num[p << 1 | 1]); } int main() { n = read(), m = read(); for(int i = 1; i <= n; i ++) { A[i].l = read(), A[i].r = read(), A[i].len = A[i].r - A[i].l; b[++ tot] = A[i].l, b[++ tot] = A[i].r; } sort(A + 1, A + 1 + n); sort(b + 1, b + 1 + tot); b[0] = -1; for(int i = 1; i <= tot; i ++) if(b[i] != b[i - 1]) Map[b[i]] = ++ cnt; sort(A + 1, A + 1 + n); for(int i = 1; i <= n; i ++) A[i].l = Map[A[i].l], A[i].r = Map[A[i].r]; for(int i = 1, j = 1; i <= n; i ++) { update(1, 1, cnt, A[i].l, A[i].r, 1); if(num[1] < m) continue; int tem = A[i].len, tem2 = 0; while(num[1] >= m) { tem2 = A[j].len; update(1, 1, cnt, A[j].l, A[j].r, -1), j ++; } ans = min(ans, tem - tem2); } if(ans == INF) printf("-1\n"); else printf("%d\n", ans); return 0; }

【題解】NOI2016序列