题意:用m个区间去覆盖1~n,求最小使用数。

题解:线段树,覆盖[l,r]:找出线段树上含了l的最小的区间数x,让线段树[l,r]区间取它本身与x的最小值,最后在求n处的最小值即可,复杂度O(mlogn)。开始的时候还想pushdown等操作,结果超时,后来一算发现直接暴力线段树更好。

View Code
 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 const int N=50005,M=500005;
 6 const int inf=1<<29;
 7 struct Line
 8 {
 9     int left,right,val;
10 }line[N*4];
11 struct data
12 {
13     int x,y;
14     bool operator<(const data &ne)const
15     {
16         if(x!=ne.x)
17             return x<ne.x;
18         else
19             return y<ne.y;
20     }
21 }po[M];
22 void build(int now,int left,int right)
23 {
24     line[now].left=left;
25     line[now].right=right;
26     line[now].val=inf;
27     if(left==right)
28         return;
29     int mid=(left+right)>>1;
30     build(now*2,left,mid);
31     build(now*2+1,mid+1,right);
32 }
33 int getpos(int now,int pos)
34 {
35     int ll=line[now].left,rr=line[now].right,mid=(ll+rr)>>1;
36     if(ll==rr)
37         return line[now].val;
38     else if(pos<=mid)
39         return min(line[now].val,getpos(now*2,pos));
40     else
41         return min(line[now].val,getpos(now*2+1,pos));
42 }
43 void modify(int now,int left,int right,int v)
44 {
45     int ll=line[now].left,rr=line[now].right,mid=(ll+rr)>>1,val=line[now].val;
46     if(ll==left&&rr==right)
47     {
48         line[now].val=min(val,v);
49         return;
50     }
51     if(right<=mid)
52         modify(now*2,left,right,v);
53     else if(left>mid)
54         modify(now*2+1,left,right,v);
55     else
56     {
57         modify(now*2,left,mid,v);
58         modify(now*2+1,mid+1,right,v);
59     }
60 }
61 int main()
62 {
63     int n,m;
64     while(scanf("%d%d",&n,&m)!=EOF)
65     {
66         build(1,1,n);
67         modify(1,1,1,0);
68         for(int i=0;i<m;i++)
69         {
70             scanf("%d%d",&po[i].x,&po[i].y);
71             int x=max(po[i].x,1),y=min(po[i].y,n);
72             int tp=getpos(1,x);
73             if(tp==inf)
74                 continue;
75             modify(1,x,y,tp+1);
76         }
77         printf("%d\n",getpos(1,n));
78     }
79     return 0;
80 }