如果不考虑字典序的话,直接按右端点排序,能选就选,就可以算出ans……
但是要算一个字典序最小的解就比较蛋疼了= =
Orz了zyf的题解
就是按字典序从小到大依次枚举,在不改变答案的情况下,能加进来就加。
但我想错的地方是:如果第 i 个可以在某个最优解的情况下就加入它(即判断[1,n])。但这样最后得到的可能并不是一组合法解。
所以用set维护前驱后继,判断[l,r]这一段才可以……
P.S.BZOJ200题留念
1 /************************************************************** 2 Problem: 1178 3 User: Tunix 4 Language: C++ 5 Result: Accepted 6 Time:4008 ms 7 Memory:41124 kb 8 ****************************************************************/ 9 10 //BZOJ 1178 11 #include<set> 12 #include<vector> 13 #include<cstdio> 14 #include<cstdlib> 15 #include<cstring> 16 #include<iostream> 17 #include<algorithm> 18 #define rep(i,n) for(int i=0;i<n;++i) 19 #define F(i,j,n) for(int i=j;i<=n;++i) 20 #define D(i,j,n) for(int i=j;i>=n;--i) 21 #define pb push_back 22 using namespace std; 23 24 int getint(){ 25 int v=0,sign=1; char ch=getchar(); 26 while(ch<'0'||ch>'9') {if (ch=='-') sign=-1; ch=getchar();} 27 while(ch>='0'&&ch<='9') {v=v*10+ch-'0'; ch=getchar();} 28 return v*sign; 29 } 30 typedef long long LL; 31 const int maxn=200010; 32 #define debug 33 /*******************template********************/ 34 struct rec{int x,y,z;}a[maxn],b[maxn],c[maxn],L,R; 35 set<rec> s; 36 set<rec> :: iterator itl,itr; 37 bool cmp1(rec a,rec b){ 38 return a.x<b.x || (a.x==b.x && a.y>b.y); 39 } 40 bool cmp2(rec a,rec b){ 41 return a.z<b.z; 42 } 43 bool operator < (rec a,rec b){return a.x<b.x;} 44 int A[maxn*2],B[maxn*2],d[maxn*2][19],n,m,N,M,ans; 45 46 void ready(){ 47 sort(B+1,B+M+1); 48 N=unique(B+1,B+M+1)-B-1; 49 F(i,1,m){ 50 b[i].x=lower_bound(B+1,B+N+1,b[i].x)-B; 51 b[i].y=lower_bound(B+1,B+N+1,b[i].y)-B; 52 } 53 sort(b+1,b+m+1,cmp1); 54 int j=0x3f3f3f3f; 55 D(i,m,1) if (b[i].y<j) j=b[i].y,a[++n]=b[i]; 56 F(i,1,n) c[i]=a[n-i+1]; 57 memcpy(a,c,sizeof(c)); 58 memset(d,0x3f,sizeof(d)); 59 j=n; 60 D(i,N,1){ 61 d[i][0]=d[i+1][0]; 62 if (a[j].x==i) d[i][0]=min(d[i][0],a[j].y); 63 F(k,1,17) if (d[i][k-1]!=0x3f3f3f3f) d[i][k]=d[d[i][k-1]+1][k-1]; 64 for(;j&&a[j].x==i;j--); 65 } 66 } 67 int calc(int l,int r){ 68 int ans=0; 69 D(i,17,0) if (d[l][i]<=r) l=d[l][i]+1,ans+=1<<i; 70 return ans; 71 } 72 73 int main(){ 74 #ifndef ONLINE_JUDGE 75 freopen("input.txt","r",stdin); 76 #endif 77 m=getint(); 78 F(i,1,m){ 79 B[++M]=b[i].x=getint(); 80 B[++M]=b[i].y=getint(); 81 b[i].z=i; 82 } 83 ready(); 84 printf("%d\n",calc(1,N)); 85 memcpy(a,b,sizeof(b)); 86 sort(a+1,a+m+1,cmp2); 87 L.x=0,L.y=2,R.x=N+1,R.y=1; 88 s.insert(L); s.insert(R); 89 int l,r; 90 F(i,1,m){ 91 L.x=a[i].x,L.y=1,R.x=a[i].y,R.y=2; 92 itl=s.lower_bound(L); 93 itr=s.upper_bound(R); 94 if (itl!=itr||itr->y==2) continue; 95 itl--; l=itl->x+1; r=itr->x-1; 96 if (calc(l,a[i].x-1)+calc(a[i].y+1,r)+1!=calc(l,r)) continue; 97 s.insert(L); s.insert(R); 98 printf("%d ",a[i].z); 99 } 100 return 0; 101 }