Newcoder 13 F.監視任務(貪心+BIT)
阿新 • • 發佈:2018-12-18
Description
在課餘會接受一些民間的鷹眼類委託,即遠距離的狙擊監視防衛。 一共接到了份委託,這些委託與個直線排布的監視點相關。 第份委託的內容為:對於區間中的監視點,至少要防衛其中的個。 必須完成全部委託,並且希望選取儘量少的監視點來防衛。
Input
第一行,兩個正整數。
接下來行,每行三個整數。
Output
一行,一個整數,即所需防衛的最少監視點數量。
Sample Input
11 5 3 7 3 8 10 3 6 8 1 1 3 1 10 11 1
Sample Output
6
Solution
貪心,把所有區間按右端點排序,每次儘可能往右邊放監視點,用樹狀陣列維護監視點以便快速查詢當前考慮區間是否合法,時間複雜度
Code
#include<cstdio> #include<iostream> #include<cstring> #include<algorithm> #include<cmath> #include<vector> #include<queue> #include<map> #include<set> #include<ctime> using namespace std; typedef long long ll; typedef pair<int,int>P; const int INF=0x3f3f3f3f,maxn=1000005; struct BIT { #define lowbit(x) (x&(-x)) int b[maxn],n; void init(int _n) { n=_n; for(int i=1;i<=n;i++)b[i]=0; } void update(int x,int v) { while(x<=n) { b[x]+=v; x+=lowbit(x); } } int query(int x) { int ans=0; while(x) { ans+=b[x]; x-=lowbit(x); } return ans; } }bit; int n,m,vis[maxn]; struct node { int l,r,k; bool operator<(const node&b)const { if(r!=b.r)return r<b.r; if(l!=b.l)return l<b.l; return k>b.k; } }a[maxn]; int main() { scanf("%d%d",&n,&m); for(int i=1;i<=m;i++)scanf("%d%d%d",&a[i].l,&a[i].r,&a[i].k); sort(a+1,a+m+1); bit.init(n); for(int i=1;i<=m;i++) { int l=a[i].l,r=a[i].r,k=a[i].k; int num=bit.query(r)-bit.query(l-1); if(num>=k)continue; for(int j=r;j>=l;j--) if(!vis[j]) { vis[j]=1; num++; bit.update(j,1); if(num==k)break; } } printf("%d\n",bit.query(n)); return 0; }