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

    3192: [JLOI2013]删除物品

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 668  Solved: 400
    [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

    Source

    【思路】

             区间求和+单点修改。

             十分巧妙地重组数据,例如将样例重组为541273,给定两个指针t1/t2,分别指向两堆的top,这样所谓的移动操作就变成了堆顶指针的滑动了。存在设1,单点修改,BIT求和即可。

             注意ans为long long。

    【代码】

             

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<iostream>
     4 #include<algorithm>
     5 #define FOR(a,b,c) for(int a=(b);a<=(c);a++)
     6 using namespace std;
     7 
     8 typedef long long LL;
     9 const int maxn = 100000+10;
    10 
    11 int read() {
    12     char c=getchar();
    13     while(!isdigit(c)) c=getchar();
    14     int x=0;
    15     while(isdigit(c)) {
    16         x=x*10+c-'0';
    17         c=getchar();
    18     }
    19     return x;
    20 }
    21 
    22 int a[maxn],rank[maxn],tmp[maxn];
    23 int n,m,t1,t2;
    24 
    25 int cmp(const int& i,const int& j) { return a[i]>a[j];
    26 }
    27 
    28 int c[maxn];
    29 int lowbit(int x) { return x&(-x);
    30 }
    31 void Add(int x,int d) {
    32     while(x<=n) {
    33         c[x]+=d;
    34         x+=lowbit(x);
    35     }
    36 }
    37 int Sum(int x) {
    38     int res=0;
    39     while(x>0) {
    40         res+=c[x];
    41         x-=lowbit(x);
    42     }
    43     return res;
    44 }
    45 int main() {
    46     n=read(),m=read();
    47     t1=n,t2=t1+1;
    48     FOR(i,1,n) a[i]=read();
    49     FOR(i,n+1,n+m) a[i]=read();
    50     FOR(i,1,n) tmp[i]=a[n-i+1];
    51     FOR(i,1,n) a[i]=tmp[i];
    52     n += m;
    53     FOR(i,1,n) rank[i]=i,Add(i,1);
    54     
    55     sort(rank+1,rank+n+1,cmp);
    56     
    57     LL ans=0;                 //long long型 
    58     FOR(i,1,n) {
    59         int t=rank[i];
    60         if(t>=t2) {
    61             ans+=Sum(t)-Sum(t2-1)-1;
    62             Add(t,-1);
    63             t2=t;t1=t2-1;
    64         }
    65         else {
    66             ans+=Sum(t1)-Sum(t-1)-1;
    67             Add(t,-1);
    68             t1=t; t2=t1+1;
    69         }
    70     }
    71     printf("%lld
    ",ans);
    72     return 0;
    73 }
  • 相关阅读:
    存储过程使用:
    java map,set,list
    Jbox帮助文档,默认的属性含义
    checkboxlist的说明及使用
    java中两种select方式,,一种从数据表中读取
    IE6下<a href="#">与<a href="javascript:void(0);">的区别
    用javascript如何在框架间传值
    a href=#与 a href=javascript:void(0) 的区别
    关于如何导入GPUImage
    GPUImage实现过程
  • 原文地址:https://www.cnblogs.com/lidaxin/p/4981762.html
Copyright © 2011-2022 走看看