标签:
题意:
最少需要多少个区间能完全覆盖整个区间[1,n]
分析:
dp[i]表示覆盖[1,i]最少需要的区间数,对于区间[a,b],dp[b]=min(dp[a...b-1])+1;用线段树来维护区间最小值。
#include <map> #include <set> #include <list> #include <cmath> #include <queue> #include <stack> #include <cstdio> #include <vector> #include <string> #include <cctype> #include <complex> #include <cassert> #include <utility> #include <cstring> #include <cstdlib> #include <iostream> #include <algorithm> using namespace std; typedef pair<int,int> PII; typedef long long ll; #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define All 1,N,1 #define N 50010 #define read freopen("in.txt", "r", stdin) const ll INFll = 0x3f3f3f3f3f3f3f3fLL; const int INF= 0x7ffffff; const int mod = 1000000007; struct seg{ int s,e; }g[N*10]; int minv[N*4],n,q; void pushup(int rt){ minv[rt]=min(minv[rt<<1],minv[rt<<1|1]); } void build(int l,int r,int rt){ if(l==r){ if(l==1)minv[rt]=0; else minv[rt]=INF; return; } int m=(l+r)>>1; build(lson); build(rson); pushup(rt); } void update(int p,int l,int r,int rt,int v){ if(l==r){ minv[rt]=min(minv[rt],v); return; } int m=(l+r)>>1; if(p<=m)update(p,lson,v); else update(p,rson,v); pushup(rt); } int query(int L,int R,int l,int r,int rt){ if(l>=L&&r<=R) return minv[rt]; int tmp=INF; int m=(l+r)>>1; if(L<=m)tmp=min(tmp,query(L,R,lson)); if(R>m)tmp=min(tmp,query(L,R,rson)); return tmp; } int main() { int t; scanf("%d",&t); while(t--){ scanf("%d%d",&n,&q); for(int i=0;i<q;++i) scanf("%d%d",&g[i].s,&g[i].e); build(1,n,1); for(int i=0;i<q;++i){ int ans=min(query(g[i].s,g[i].e-1,1,n,1)+1,query(g[i].e,g[i].e,1,n,1)); update(g[i].e,1,n,1,ans); } printf("%d\n",query(n,n,1,n,1)); if(t)printf("\n"); } return 0; }
标签:
原文地址:http://www.cnblogs.com/zsf123/p/4909767.html