如果不考虑字典序的话,直接按右端点排序,能选就选,就可以算出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 }
View Code

相关文章: