zoukankan      html  css  js  c++  java
  • 【BZOJ 3387】 线段树= =

    57 跨栏训练
    为了让奶牛参与运动,约翰建造了 K 个栅栏。每条栅栏可以看做是二维平面上的一条线段,它
    们都平行于 X 轴。第 i 条栅栏所覆盖的 X 轴坐标的区间为 [ Ai,Bi ], Y 轴高度就是 i。一开始,奶牛
    在坐标 (S,K + 1) 处,它们的家在原点处,所以要想要回家就必须“跨”一些栅栏。
    但奶牛们是跨不过栅栏的,它们只能绕过栅栏。在二维平面上,它们只能沿水平和垂直方向移动,
    如果前进的道路上出现栅栏,它们就不能前进,必须沿水平方向移动到没有栅栏的地方再前进。奶牛
    们希望走的路越短越好,由于在垂直方向上的路程是确定的,你只需要帮它们求出在水平方向的最短
    路程就可以了。
    输入格式
    • 第一行:两个整数 K S, 1 K 50000, 105 S 105
    • 第二行到第 N + 1 行:第 i + 1 行有两个整数 Ai Bi105 Ai Bi 105
    输出格式
    • 单个整数:表示奶牛从起点到终点在水平方向移动的最短总距离
    样例输入
    4 0
    -2 1
    -1 2
    -3 0
    -2 1
    样例输出
    4
    解释
    第四个栅栏是最先遇到的,向右移一格绕过
    它。为了绕过第二个栅栏,再向右移一格,最后
    为了回到原点向左移两格

    【分析】

      就是,差不多,像是个模拟的东西,如果没有东西挡着你,就不用走了(如果要走,等一下有东西挡着你再走)、

      如果有东西挡着你,就走到栅栏左边或者栅栏右边(不用多走,要是需要多走,等一下再走)

      但是询问区间的话每个点到栅栏左端点需要加的距离是不一样的,所以我们维护的时候不是他走的距离,而是他走的距离在加上他走到图的最左边的距离。

      右边也一样。

      就是一个区间修改成INF的操作 以及单点修改 还有区间查询。

    代码如下:

      1 #include<cstdio>
      2 #include<cstdlib>
      3 #include<cstring>
      4 #include<iostream>
      5 #include<algorithm>
      6 #include<queue>
      7 using namespace std;
      8 #define Maxn 200010
      9 #define Maxk 50010
     10 #define INF 0xfffffff
     11 
     12 int a[Maxk],b[Maxk];
     13 
     14 struct node
     15 {
     16     int l,r,lc,rc,a1,a2;
     17     bool lazy;
     18 }t[Maxn*2];int len;
     19 
     20 int mymin(int x,int y) {return x<y?x:y;}
     21 int mymax(int x,int y) {return x>y?x:y;}
     22 int mn=INF,mx=0;
     23 
     24 int build(int l,int r)
     25 {
     26     int x=++len;
     27     t[x].l=l;t[x].r=r;t[x].a1=t[x].a2=INF;
     28     t[x].lazy=0;
     29     if(l!=r)
     30     {
     31         int mid=(l+r)>>1;
     32         t[x].lc=build(l,mid);
     33         t[x].rc=build(mid+1,r);
     34     }
     35     return x;
     36 }
     37 
     38 void upd(int x)
     39 {
     40     if(t[x].lazy==0) return;
     41     if(t[x].l!=t[x].r)
     42     {
     43         int lc=t[x].lc,rc=t[x].rc;
     44         t[lc].lazy=1;t[rc].lazy=1;
     45     }
     46     t[x].a1=t[x].a2=INF;
     47     t[x].lazy=0;
     48 }
     49 
     50 void change(int x,int l,int r)
     51 {
     52     if(l>r) return;
     53     upd(x);
     54     if(t[x].l==l&&t[x].r==r)
     55     {
     56         t[x].lazy=1;
     57         return;
     58     }
     59     int mid=(t[x].l+t[x].r)>>1;
     60     if(r<=mid) change(t[x].lc,l,r);
     61     else if(l>mid) change(t[x].rc,l,r);
     62     else
     63     {
     64         change(t[x].lc,l,mid);
     65         change(t[x].rc,mid+1,r);
     66     }
     67     int lc=t[x].lc,rc=t[x].rc;
     68     upd(lc);upd(rc);
     69     t[x].a1=mymin(t[lc].a1,t[rc].a1);
     70     t[x].a2=mymin(t[lc].a2,t[rc].a2);
     71 }
     72 
     73 void change2(int x,int y,int z)
     74 {
     75     upd(x);
     76     if(t[x].l==t[x].r)
     77     {
     78         t[x].a1=mymin(t[x].a1,z+y);
     79         t[x].a2=mymin(t[x].a2,z+mx-y);
     80         return;
     81     }
     82     int mid=(t[x].l+t[x].r)>>1;
     83     if(y<=mid) change2(t[x].lc,y,z);
     84     else change2(t[x].rc,y,z);
     85     int lc=t[x].lc,rc=t[x].rc;
     86     upd(lc);upd(rc);
     87     t[x].a1=mymin(t[lc].a1,t[rc].a1);
     88     t[x].a2=mymin(t[lc].a2,t[rc].a2);
     89 }
     90 
     91 int query(int x,int l,int r,bool p)
     92 {
     93     if(l>r) return INF;
     94     upd(x);
     95     if(t[x].l==l&&t[x].r==r)
     96     {
     97         if(!p) return t[x].a1;
     98         else return t[x].a2;
     99     }
    100     int mid=(t[x].l+t[x].r)>>1;
    101     if(r<=mid) return query(t[x].lc,l,r,p);
    102     else if(l>mid) return query(t[x].rc,l,r,p);
    103     else return mymin(query(t[x].lc,l,mid,p),query(t[x].rc,mid+1,r,p));
    104 }
    105 
    106 int main()
    107 {
    108     int k,s;
    109     scanf("%d%d",&k,&s);
    110     for(int i=1;i<=k;i++)
    111     {
    112         scanf("%d%d",&a[i],&b[i]);
    113         mn=mymin(mn,a[i]);
    114         mx=mymax(mx,b[i]);
    115     }
    116     mn=-mn+1;
    117     for(int i=1;i<=k;i++) a[i]+=mn,b[i]+=mn;
    118     mx+=mn;
    119     len=0;
    120     build(1,mx);
    121     change2(1,0+mn,0);
    122     for(int i=1;i<=k;i++)
    123     {
    124         int n1=query(1,a[i]+1,b[i]-1,0),n2=query(1,a[i]+1,b[i]-1,1);
    125         if(n1!=INF) change2(1,a[i],n1-a[i]);
    126         if(n2!=INF) change2(1,b[i],n2-(mx-b[i]) );
    127         change(1,a[i]+1,b[i]-1);
    128         
    129     }
    130     s+=mn;
    131     int ans=mymin(query(1,1,s,1)-(mx-s),query(1,s,mx,0)-s);
    132     printf("%d
    ",ans);
    133     return 0; 
    134 }
    [BZOJ 3387]

    2016-10-31 15:17:12

  • 相关阅读:
    PAT (Advanced Level) 1080. Graduate Admission (30)
    PAT (Advanced Level) 1079. Total Sales of Supply Chain (25)
    PAT (Advanced Level) 1078. Hashing (25)
    PAT (Advanced Level) 1077. Kuchiguse (20)
    PAT (Advanced Level) 1076. Forwards on Weibo (30)
    PAT (Advanced Level) 1075. PAT Judge (25)
    PAT (Advanced Level) 1074. Reversing Linked List (25)
    PAT (Advanced Level) 1073. Scientific Notation (20)
    PAT (Advanced Level) 1072. Gas Station (30)
    PAT (Advanced Level) 1071. Speech Patterns (25)
  • 原文地址:https://www.cnblogs.com/Konjakmoyu/p/6015961.html
Copyright © 2011-2022 走看看