1. 程式人生 > >bzoj4653 [Noi2016]區間

bzoj4653 [Noi2016]區間

nbsp algorithm esp void chang %d define truct include

傳送門:http://www.lydsy.com/JudgeOnline/problem.php?id=4653

【題解】

首先把區間按長度從小到大排好序。

那麽取一些區間,花費為長度最大-長度最小,相當於把這個長度區間裏面的區間都取了。

求是不是有一個位置被覆蓋超過了m次。

那麽這個用two-pointer和線段樹就能實現啦!

技術分享
# include <vector>
# include <stdio.h>
# include <string.h>
# include <iostream>
# include <algorithm>
// # include <bits/stdc++.h>
using namespace std; typedef long long ll; typedef long double ld; typedef unsigned long long ull; const int M = 5e5 + 10; const int mod = 1e9+7; # define RG register # define ST static int n, m; struct intervals { int l, r; intervals() {} intervals(int l, int r) : l(l), r(r) {} friend
bool operator < (intervals a, intervals b) { return a.r-a.l < b.r-b.l; } }p[M], a[M]; vector<int> ps; namespace SGT { const int M = 4e6 + 10; int w[M], lazy[M]; # define ls (x<<1) # define rs (x<<1|1) inline void down(int x) { if(!x) return
; if(!lazy[x]) return ; w[ls] += lazy[x], lazy[ls] += lazy[x]; w[rs] += lazy[x], lazy[rs] += lazy[x]; lazy[x] = 0; } inline void change(int x, int l, int r, int L, int R, int d) { if(L <= l && r <= R) { w[x] += d; lazy[x] += d; return ; } down(x); int mid = l+r>>1; if(L <= mid) change(ls, l, mid, L, R, d); if(R > mid) change(rs, mid+1, r, L, R, d); w[x] = max(w[ls], w[rs]); } inline int get() { return w[1]; } } int main() { cin >> n >> m; for (int i=1; i<=n; ++i) scanf("%d%d", &p[i].l, &p[i].r); sort(p+1, p+n+1); for (int i=1; i<=n; ++i) ps.push_back(p[i].l), ps.push_back(p[i].r); sort(ps.begin(), ps.end()); ps.erase(unique(ps.begin(), ps.end()), ps.end()); for (int i=1; i<=n; ++i) { a[i].l = lower_bound(ps.begin(), ps.end(), p[i].l) - ps.begin() + 1; a[i].r = lower_bound(ps.begin(), ps.end(), p[i].r) - ps.begin() + 1; } int mx = ps.size(), ans = 1e9; for (int l=1, r=0; l<=n; ++l) { if(SGT::get() != m) { while(r<n) { ++r; SGT::change(1, 1, mx, a[r].l, a[r].r, 1); if(SGT::get() == m) break; } } if(SGT::get() != m) break; ans = min(ans, p[r].r - p[r].l - p[l].r + p[l].l); SGT::change(1, 1, mx, a[l].l, a[l].r, -1); } if(ans == 1e9) cout << -1; else cout << ans; return 0; }
View Code

bzoj4653 [Noi2016]區間