• *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
    ",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
    ",Ans[1]);
    110 //    puts("");
    111     puts("3");
    112     return 0;
    113 }
    View Code
  • 相关阅读:
    腾讯本月将出QQ for Linux!
    OpenSolaris 初体验
    OpenSolaris 初体验
    简易背单词
    NetBeans 全球翻译团队Tshirt发放~
    上传图片时预览效果
    使用ATL开发ActiveX控件
    Visual Studio 2010 Visual C++ 确定要重新分发的 DLL
    动态链接导入库与静态链接库
    20110413 15:54 利用事件触发实现ActiveX调用js函数
  • 原文地址:https://www.cnblogs.com/Blue233333/p/9290901.html
Copyright © 2020-2023  润新知