• 洛谷 P3253 [JLOI2013]删除物品 解题报告


    P3253 [JLOI2013]删除物品

    题目描述

    箱子再分配问题需要解决如下问题:

    (1)一共有(N)个物品,堆成(M)堆。

    (2)所有物品都是一样的,但是它们有不同的优先级。

    (3)你只能够移动某堆中位于顶端的物品。

    (4)你可以把任意一堆中位于顶端的物品移动到其它某堆的顶端。若此物品是当前所有物品中优先级最高的,可以直接将之删除而不用移动。

    (5)求出将所有物品删除所需的最小步数。删除操作不计入步数之中。

    (6)只是一个比较难解决的问题,这里你只需要解决一个比较简单的版本: 不会有两个物品有着相同的优先级,且(M=2)

    输入输出格式

    输入格式:

    第一行是包含两个整数(N1,N2)分别表示两堆物品的个数。接下来有(N1)行整数按照从顶到底的顺序分别给出了第一堆物品中的优先级,数字越大,优先级越高。再接下来的N2行按照同样的格式给出了第二堆物品的优先级。

    输出格式:

    对于每个数据,请输出一个整数,即最小移动步数。

    说明

    (1<=N1+N2<=100000)


    说一下我做这个题的心路历程。

    1. 汉诺(n)塔问题?
    2. 两个栈?
    3. 等等,我似不似看错了,这不就是个模拟???
    4. 好像没错啊...
    5. 噫?模拟是(O(n^2))?
    6. 苟不住了估计要跑数据结构
    7. 噫,我把这一坨挪到另一个上面后它们距离当前栈顶的距离是翻转区间???
    8. 分......分块?完了不会分块啊
    9. 瞎画+摸鱼(ing)
    10. 等等,我把两个栈bu~成一个数组后不仅只用挪中间的断点了
    11. 这样我拿线段树维护一下某点左边后几个被巴拉掉了
    12. 等等,咋不对啊。模拟一下,然后我发现做断点左边的点时要额外减去1...
      最后,瞅了瞅题解。这个..别人都维护的是元素个数啊。。

    做的还是有点小麻烦的。。。


    code:

    #include <cstdio>
    #include <algorithm>
    #define ls id<<1
    #define rs id<<1|1
    #define mid (l+r>>1)
    #define R (t[id].r)
    #define L (t[id].l)
    #define Mid (L+R>>1)
    using namespace std;
    const int N=100010;
    int a[N],di,n;
    struct node2
    {
        int i,w;
        bool friend operator <(node2 n1,node2 n2)
        {
            return n1.w>n2.w;
        }
    }b[N];
    struct node
    {
        int l,r,w,lazy;
    }t[N*4];
    
    void build(int id,int l,int r)
    {
        L=l,R=r;
        if(l==r) return;
        build(ls,l,mid);
        build(rs,mid+1,r);
    }
    
    void change(int id,int l,int r)
    {
        if(L==l&&R==r)
        {
            t[id].lazy-=1;
            return;
        }
        t[id].w-=(r+1-l);
        if(r<=Mid)
            change(ls,l,r);
        else if(l>Mid)
            change(rs,l,r);
        else
        {
            change(ls,l,Mid);
            change(rs,Mid+1,r);
        }
    }
    
    void push_down(int id)
    {
        t[id].w+=t[id].lazy*(R+1-L);
        if(L!=R)
        {
            t[ls].lazy+=t[id].lazy;
            t[rs].lazy+=t[id].lazy;
        }    
        t[id].lazy=0;
    }
    
    int query(int id,int loc)
    {
        push_down(id);
        if(L==R)
            return t[id].w;
        if(loc<=Mid)
            return query(ls,loc);
        else
            return query(rs,loc);
    }
    long long ans=0;
    int main()
    {
        int n1,n2;
        scanf("%d%d",&n1,&n2);
        for(int i=n1;i>=1;i--)
            scanf("%d",a+i);
        di=n1;n=n1+n2;
        for(int i=1;i<=n2;i++)
            scanf("%d",a+i+n1);
        for(int i=1;i<=n;i++)
            b[i].i=i,b[i].w=a[i];
        sort(b+1,b+1+n);
        build(1,1,n);
        int now=b[1].i;
        ans+=abs(now-di);
        if(now>di) ans--;
        di=now;
        if(now!=n) change(1,now+1,n);
        for(int i=2;i<=n;i++)
        {
            now=b[i].i;
            int q1=query(1,now),q2=query(1,di);
            ans+=abs(now+q1-di-q2);
            if(now<di) ans--;
            if(now!=n) change(1,now+1,n);
            di=now;
        }
        printf("%lld
    ",ans);
        return 0;
    }
    

    2018.5.20

  • 相关阅读:
    P1121 环状最大两段子段和
    (转)背包9讲
    P1115 最大子段和
    P1108 低价购买
    P1103 书本整理
    P1095 守望者的逃离
    P1091 合唱队形
    P1077 摆花
    hadoop记录topk
    楼天城楼教主的acm心路历程(作为励志用)
  • 原文地址:https://www.cnblogs.com/butterflydew/p/9064473.html
Copyright © 2020-2023  润新知