[BZOJ 3387] Fence Obstacle Course

[题目链接]

          https://www.lydsy.com/JudgeOnline/problem.php?id=3387

[算法]

          f[i][0]表示从第i个栅栏的左端点走到原点的最少移动步数

          f[i][1]表示从第i个栅栏的右端点走到原点的最少移动步数

          我们可以用线段树优化转移

[代码]

        

#include<bits/stdc++.h>
using namespace std;
#define MAXN 50010
const int V = 100010;

struct info
{
        int x,y;
} a[MAXN];

int i,N,S,x,y;
int f[MAXN][2];

struct SegmentTree
{
        struct Node
        {
                int l,r;
                int mx,tag;
        }    Tree[V << 4];
        inline void build(int index,int l,int r)
        {
                int mid;
                Tree[index].l = l;
                Tree[index].r = r;
                Tree[index].mx = Tree[index].tag = 0;
                if (l == r) return;
                mid = (l + r) >> 1;
                build(index << 1,l,mid);
                build(index << 1 | 1,mid + 1,r);
        }
        inline void pushdown(int index)
        {
                if (Tree[index].tag)
                {
                        Tree[index << 1].mx = max(Tree[index << 1].mx,Tree[index].tag);
                        Tree[index << 1 | 1].mx = max(Tree[index << 1 | 1].mx,Tree[index].tag);
                        Tree[index << 1].tag = max(Tree[index << 1].tag,Tree[index].tag);
                        Tree[index << 1 | 1].tag = max(Tree[index << 1 | 1].tag,Tree[index].tag);
                        Tree[index].tag = 0;
                }
        }
        inline void modify(int index,int l,int r,int val)
        {
                int mid;
                if (Tree[index].l == l && Tree[index].r == r)
                {
                        Tree[index].mx = Tree[index].tag = val;
                        return;
                }
                pushdown(index);
                mid = (Tree[index].l + Tree[index].r) >> 1;
                if (mid >= r) modify(index << 1,l,r,val);
                else if (mid + 1 <= l) modify(index << 1 | 1,l,r,val);
                else
                {
                        modify(index << 1,l,mid,val);
                        modify(index << 1 | 1,mid + 1,r,val);
                }
        }
        inline int query(int index,int pos)
        {
                int mid;
                if (Tree[index].l == Tree[index].r) return Tree[index].mx;
                pushdown(index);
                mid = (Tree[index].l + Tree[index].r) >> 1;
                if (mid >= pos) return query(index << 1,pos);
                else return query(index << 1 | 1,pos);
        }
} T;

int main() 
{
        
        scanf("%d%d",&N,&S);
        S += V;
        for (i = 1; i <= N; i++) 
        {
                scanf("%d%d",&a[i].x,&a[i].y);        
                a[i].x += V; 
                a[i].y += V;
        }
        T.build(1,1,V << 1);
        f[0][0] = f[0][1] = 0;
        a[0].x = a[0].y = V;
        for (i = 1; i <= N; i++)
        {
                x = T.query(1,a[i].x);
                y = T.query(1,a[i].y);
                f[i][0] = min(f[x][0] + abs(a[i].x - a[x].x),f[x][1] + abs(a[i].x - a[x].y));
                f[i][1] = min(f[y][0] + abs(a[i].y - a[y].x),f[y][1] + abs(a[i].y - a[y].y));    
                T.modify(1,a[i].x,a[i].y,i);
        }
        printf("%d\n",min(abs(S - a[N].x) + f[N][0],abs(S - a[N].y) + f[N][1]));
        
        return 0;
    
}

 

posted @ 2018-07-24 10:52  evenbao  阅读(164)  评论(0编辑  收藏  举报