贪心地,可以建出一棵树,每个区间对应一个点,它的父亲是它右边的、与它不相交的、右端点最小的区间。
为了方便,再加入一个[0,0]区间
于是就可以倍增来做出从某个区间开始,一直到某个右界,这之中最多能选多少区间
这样的话,可以从[0,0]区间,倍增做出第一问的答案
考虑第二问,我们需要尽量选编号小的区间,于是只要判断我们如果选了这个区间 还能不能选够那么多就可以了
而且前面已经选过的就钦定住了
开一个set来放下已经选过的区间,按左端点从小到大排序
为了方便,一开始先把[0,0]区间和[inf,inf]区间加进去。设当前区间是x
这样的话,只要找到前驱pre、后继nxt,判断pre、nxt是否和x相交,相交就不做了
然后看从pre到nxt能选几个、(pre到x)+(x到nxt)+1能选几个,看看是否相等,来判断选不选x
1 #include<bits/stdc++.h> 2 #define pa pair<int,int> 3 #define CLR(a,x) memset(a,x,sizeof(a)) 4 using namespace std; 5 typedef long long ll; 6 const int maxn=2e5+10,inf=1e9+1; 7 8 inline ll rd(){ 9 ll x=0;char c=getchar();int neg=1; 10 while(c<'0'||c>'9'){if(c=='-') neg=-1;c=getchar();} 11 while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar(); 12 return x*neg; 13 } 14 15 struct Node{ 16 int l,r,i; 17 Node (int a=0,int b=0,int c=0){l=a,r=b,i=c;} 18 }pos[maxn],pos2[maxn],pos3[maxn]; 19 bool operator < (Node a,Node b){return a.l<b.l;} 20 int N,M; 21 int ma[maxn*2],fa[maxn][20],cnt[maxn][20]; 22 set<Node> st; 23 bool flag[maxn]; 24 25 inline bool cmp(Node a,Node b){return a.l<b.l;} 26 inline bool cmp2(Node a,Node b){return a.r<b.r;} 27 28 inline int getst(int x,int bnd){ 29 int re=0; 30 for(int i=18;i>=0;i--){ 31 if(fa[x][i]&&pos2[fa[x][i]].r<bnd) 32 re+=cnt[x][i],x=fa[x][i]; 33 } 34 return re; 35 } 36 37 int main(){ 38 //freopen("","r",stdin); 39 int i,j,k; 40 N=rd(); 41 for(i=1,j=0;i<=N;i++){ 42 pos[i].l=rd(),pos[i].r=rd();pos[i].i=i; 43 } 44 memcpy(pos2,pos,sizeof(pos)); 45 memcpy(pos3,pos,sizeof(pos)); 46 sort(pos+1,pos+N+1,cmp); 47 sort(pos3+1,pos3+N+1,cmp2); 48 int mm=inf,mi=0; 49 for(i=N,j=N;i;i--){ 50 for(;pos[j].l>pos3[i].r;j--){ 51 if(pos[j].r<mm) mm=pos[j].r,mi=pos[j].i; 52 } 53 int x=pos3[i].i; 54 fa[x][0]=mi;cnt[x][0]=1; 55 // printf("%d %d ",x,fa[x][0]); 56 for(k=0;fa[x][k]&&fa[fa[x][k]][k];k++){ 57 fa[x][k+1]=fa[fa[x][k]][k]; 58 cnt[x][k+1]=cnt[x][k]+cnt[fa[x][k]][k]; 59 } 60 } 61 fa[N+1][0]=pos3[1].i;cnt[N+1][0]=1; 62 for(k=0;fa[N+1][k]&&fa[fa[N+1][k]][k];k++){ 63 fa[N+1][k+1]=fa[fa[N+1][k]][k]; 64 cnt[N+1][k+1]=cnt[N+1][k]+cnt[fa[N+1][k]][k]; 65 } 66 printf("%d ",getst(N+1,inf)); 67 68 st.insert(Node(0,0,N+1));st.insert(Node(inf,inf,N+2)); 69 for(i=1;i<=N;i++){ 70 set<Node>::iterator it=st.lower_bound(pos2[i]); 71 Node nxt=*it; 72 Node pre=*(--it); 73 if(nxt.l<=pos2[i].r||pre.r>=pos2[i].l) continue; 74 int n1=getst(pre.i,pos2[i].l)+getst(i,nxt.l)+1; 75 int nn=getst(pre.i,nxt.l); 76 // printf("%d %d %d %d %d ",i,pre.i,nxt.i,nn,n1); 77 if(n1<nn) continue; 78 flag[i]=1; 79 st.insert(pos2[i]); 80 } 81 for(i=1;i<=N;i++) if(flag[i]) printf("%d ",i); 82 return 0; 83 }