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

  • 相关阅读:
    C#图片处理示例(裁剪,缩放,清晰度,水印)
    lucene4.5近实时搜索
    mongo 多条件 查询
    Lucene:QueryParser
    Lucene的中文分词器IKAnalyzer
    Lucene为不同字段指定不同分词器(转)
    Thrift初用小结
    lucene4.0与之前版本的一些改变
    lucene 资料
    Mongodb快速入门之使用Java操作Mongodb
  • 原文地址:https://www.cnblogs.com/Konjakmoyu/p/6015961.html
Copyright © 2011-2022 走看看