*LOJ#2134. 「NOI2015」小园丁与老司机

$n \leq 5e4$个平面上的点,从原点出发,能从当前点向左、右、上、左上或右上到达该方向最近的给定点。问三个问:一、最多经过多少点;二、前一问的方案;三、其所有方案种非左右走的边至少要开几辆挖掘机走完,挖掘机能从任意点出发,走路方式跟上面一样。

前两问:

纵坐标是增的可在不同层之间直接dp。同层的话,如果从左边的点x到一个右边的点y,那最优情况是x往左走,走到不能走再往右,直到y;从右边的点走到左边的点同理。dp后记一下前驱可以回答第二问。至于由谁转移过来,可以用数据结构存一下$y$、$y+x$、$y-x$的值。

第三问:上下界最大流,不会。

  1 //#include<iostream>
  2 #include<cstring>
  3 #include<cstdio>
  4 //#include<math.h>
  5 #include<set>
  6 //#include<queue>
  7 //#include<bitset>
  8 //#include<vector>
  9 #include<algorithm>
 10 #include<stdlib.h>
 11 using namespace std;
 12 
 13 #define LL long long
 14 int qread()
 15 {
 16     char c; int s=0,f=1; while ((c=getchar())<'0' || c>'9') (c=='-') && (f=-1);
 17     do s=s*10+c-'0'; while ((c=getchar())>='0' && c<='9'); return s*f;
 18 }
 19 
 20 //Pay attention to '-' , LL and double of qread!!!!
 21 
 22 int n;
 23 #define maxn 50011
 24 struct Poi{int x,y,id; bool operator < (const Poi &b) const {return y<b.y || (y==b.y && x<b.x);} }p[maxn];
 25 
 26 struct snode{int v,id; bool operator < (const snode &b) const {return v<b.v;} };
 27 set<snode> s,s1,s2;
 28 
 29 #define IT set<snode>::iterator
 30 int f[maxn],pre[maxn],tt[maxn],ppt[maxn]; bool cf[maxn];
 31 
 32 int Ans[maxn],lans=0;
 33 int main()
 34 {
 35     n=qread();
 36     for (int i=1;i<=n;i++) {p[i].x=qread(); p[i].y=qread(); p[i].id=i;}
 37     sort(p+1,p+1+n); p[n+1].y=0x3f3f3f3f; p[0].y=-1;
 38     f[0]=0; s.insert((snode){0,0}); s1.insert((snode){0,0}); s2.insert((snode){0,0});
 39     for (int i=1,j=1;i<=n;i++)
 40     {
 41         f[i]=-0x3f3f3f3f;
 42         snode now=(snode){p[i].x,i}; IT it=s.lower_bound(now);
 43         if (it!=s.end() && (*it).v==now.v)
 44         {
 45             if (f[i]<f[(*it).id]+1) {f[i]=f[(*it).id]+1; pre[i]=(*it).id; cf[i]=0;}
 46             if (f[i]<tt[(*it).id]+1) {f[i]=tt[(*it).id]+1; pre[i]=(*it).id; cf[i]=1;}
 47             s.erase(it);
 48         }s.insert(now);
 49         now=(snode){p[i].y-p[i].x,i}; it=s1.lower_bound(now);
 50         if (it!=s1.end() && (*it).v==now.v)
 51         {
 52             if (f[i]<f[(*it).id]+1) {f[i]=f[(*it).id]+1; pre[i]=(*it).id; cf[i]=0;}
 53             if (f[i]<tt[(*it).id]+1) {f[i]=tt[(*it).id]+1; pre[i]=(*it).id; cf[i]=1;}
 54             s1.erase(it);
 55         }s1.insert(now);
 56         now=(snode){p[i].y+p[i].x,i}; it=s2.lower_bound(now);
 57         if (it!=s2.end() && (*it).v==now.v)
 58         {
 59             if (f[i]<f[(*it).id]+1) {f[i]=f[(*it).id]+1; pre[i]=(*it).id; cf[i]=0;}
 60             if (f[i]<tt[(*it).id]+1) {f[i]=tt[(*it).id]+1; pre[i]=(*it).id; cf[i]=1;}
 61             s2.erase(it);
 62         }s2.insert(now);
 63         
 64         if (p[i].y!=p[i+1].y)
 65         {
 66             for (int k=j;k<=i;k++) tt[k]=ppt[k]=-0x3f3f3f3f;
 67             for (int k=j+1,tmp=j,tot=1;k<=i;k++,tot++)
 68             {
 69                 if (tt[k]<tot+f[tmp]) {tt[k]=tot+f[tmp]; ppt[k]=tmp;}
 70                 if (f[k]>f[tmp]) tmp=k;
 71             }
 72             for (int k=i-1,tmp=i,tot=1;k>=j;k--,tot++)
 73             {
 74                 if (tt[k]<tot+f[tmp]) {tt[k]=tot+f[tmp]; ppt[k]=tmp;}
 75                 if (f[k]>f[tmp]) tmp=k;
 76             }
 77             j=i+1;
 78         }
 79 //        cout<<p[i].id<<' '<<f[i]<<' '<<pre[i]<<' '<<cf[i]<<endl;
 80     }
 81     
 82     int ans=0,id=0; bool ccf=0;
 83     for (int i=1;i<=n;i++) if (f[i]>ans) ans=f[i],ccf=0,id=i;
 84     for (int i=1;i<=n;i++) if (tt[i]>ans) ans=tt[i],ccf=1,id=i;
 85     printf("%d\n",ans);
 86     int x=id;
 87     while (x)
 88     {
 89         Ans[++lans]=p[x].id;
 90         if (!ccf) {ccf^=cf[x]; x=pre[x];}
 91         else
 92         {
 93             int y=ppt[x]; ccf=0;
 94             if (y>x)
 95             {
 96                 for (int j=x+1;j<y;j++) Ans[++lans]=p[j].id;
 97                 for (int j=y;j<=n+1;j++) if (p[j].y!=p[y].y)
 98                 {for (int k=j-1;k>y;k--) Ans[++lans]=p[k].id; break;}
 99             }
100             else
101             {
102                 for (int j=x-1;j>y;j--) Ans[++lans]=p[j].id;
103                 for (int j=y;j>=0;j--) if (p[j].y!=p[y].y)
104                 {for (int k=j+1;k<y;k++) Ans[++lans]=p[k].id; break;}
105             }
106             x=y;
107         }
108     }
109     for (int i=lans;i>1;i--) printf("%d ",Ans[i]); printf("%d\n",Ans[1]);
110 //    puts("");
111     puts("3");
112     return 0;
113 }
View Code

 

posted @ 2018-07-10 18:37  Blue233333  阅读(291)  评论(0编辑  收藏  举报