zoukankan      html  css  js  c++  java
  • BZOJ3192: [JLOI2013]删除物品

    3192: [JLOI2013]删除物品

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 1072  Solved: 615
    [Submit][Status][Discuss]

    Description

     
    箱子再分配问题需要解决如下问题:
     (1)一共有N个物品,堆成M堆。
     (2)所有物品都是一样的,但是它们有不同的优先级。
     (3)你只能够移动某堆中位于顶端的物品。
     (4)你可以把任意一堆中位于顶端的物品移动到其它某堆的顶端。若此物品是当前所有物品中优先级最高的,可以直接将之删除而不用移动。
     
    (5)求出将所有物品删除所需的最小步数。删除操作不计入步数之中。
     (6)只是一个比较难解决的问题,这里你只需要解决一个比较简单的版本:
             不会有两个物品有着相同的优先级,且M=2
     

    Input

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

    Output

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

    Sample Input

    3 3
    1
    4
    5
    2
    7
    3

    Sample Output

    6

    HINT

    1<=N1+N2<=100000

    思路{

      一眼看上去是LCT板子题啊...直接维护子树大小就可以了...然而没有码出来.那有没有更好的方法呢??

      发现删除一个的代价是把它上面的移走.考虑快速搞.

      发现把两个堆拼在一坨,:1->顶 顶->1;那么就可以解决移动的问题了.

      代价的话用树状数组查询到顶端,也就是中间空格的距离就可以了.

      查询完一个数的代价记得要在位置上删除代价,并把它变成空格.

    }

    #include<bits/stdc++.h>
    #define RG register
    #define il inline
    #define db double
    #define LL long long
    #define N 100010
    #define lowbit ( i & -i )
    using namespace std;
    int tree[N],n,m,sub[N],a[N];
    void Insert(int pos,int delta){for(int i=pos;i<=n+m+1;i+=lowbit)tree[i]+=delta;return;}
    int Query(int pos){int sum(0);for(int i=pos;i;i-=lowbit)sum+=tree[i];return sum;}
    int pos[N];
    int main(){
      scanf("%d%d",&n,&m);
      for(int i=n;i;i--){
        scanf("%d",&a[i]);
        sub[++sub[0]]=a[i];
      }
      for(int i=n+2;i<=n+m+1;i++){
        scanf("%d",&a[i]);
        sub[++sub[0]]=a[i];
      }
      sort(sub+1,sub+sub[0]+1);
      int sz=unique(sub+1,sub+sub[0]+1)-sub-1;
      for(int i=1;i<=n+m+1;++i)
        if(i!=n+1){
          a[i]=lower_bound(sub+1,sub+sz+1,a[i])-sub;
          pos[a[i]]=i;
        }
      for(int i=1;i<=n+m+1;++i)if(i!=n+1)Insert(i,1);
      int cle=n+1;LL Ans(0);
      for(int i=n+m;i;--i){
        Ans+=Query(max(pos[i],cle))-Query(min(pos[i],cle)-1)-1;
        cle=pos[i];
        Insert(pos[i],-1);
      }cout<<Ans;
      return 0;
    }
    

      

  • 相关阅读:
    构建简单的二叉树(C)
    C指針淺析(3)
    C語言函數
    C# 細節(2)
    如何做好软件架构设计
    C# 細節(1)
    .NET Framework格式化字符串
    Windows下通过删除硬盘分区直接强行移除Fedora后恢复Windows启动项的方法
    DreamWeaver使用技巧学习心得
    MyEclipse使用心得、快捷键、设置
  • 原文地址:https://www.cnblogs.com/zzmmm/p/7487345.html
Copyright © 2011-2022 走看看