• bzoj3192 [JLOI2013]删除物品


    题意:给你两个栈,给你一开始的分配。每次移动一个栈顶的元素放到另一个栈顶花费1。

    并且你可以删除一个栈顶元素,花费0。

    问你从大到小删除所有数的花费。

    n1+n2<=1e5。

    标程:

     1 #include<cstdio>
     2 #include<algorithm>
     3 using namespace std;
     4 typedef long long ll;
     5 const int N=100005;
     6 int n1,n2,n,a[N],bit[N],b[N];
     7 ll ans;
     8 
     9 int lowbit(int x){return x&(-x);}
    10 
    11 int qry(int x){int res=0;while (x) res+=bit[x],x-=lowbit(x);return res;}
    12 
    13 void del(int x) {while (x<=n) bit[x]--,x+=lowbit(x);}
    14 
    15 bool cmp(int A,int B) {return a[A]>a[B];}
    16 
    17 int main()
    18 {
    19     scanf("%d%d",&n1,&n2);
    20     for (int i=n1;i>=1;i--) scanf("%d",&a[i]);
    21     for (int i=n1+1;i<=n1+n2;i++) scanf("%d",&a[i]);
    22     n=n1+n2;
    23     for (int i=1;i<=n;i++) b[i]=i,bit[i]=lowbit(i);
    24     sort(b+1,b+n+1,cmp);
    25     for (int i=1;i<=n;i++)
    26     {
    27         if (b[i]<=n1) ans+=qry(n1)-qry(b[i]);//在第一段中
    28         else ans+=qry(b[i])-qry(n1)-1;//在第二段中 
    29         n1=b[i]-1;del(b[i]); 
    30     }
    31     printf("%lld
    ",ans);
    32     return 0;
    33 } 

    题解:树状数组+栈对顶

    将两个栈的顶部连在一起变成一个数组。那么从当前最大移动到次大的路径就是中间的距离(元素个数)。删掉一个最大元素则经过其的所有路径都-1,用树状数组维护距离,当前点-1即可。

    小技巧:统计距离的话,初始化把树状数组每一位的值设成lowbit(i)。

    固定n1位第一栈的顶,方便讨论,要讨论b[i]和n1的左右位置关系。

    水题都切不动了啊,你还有什么用。加油!多做题多熟悉技巧!

  • 相关阅读:
    (转)Linux系统中sysctl命令详解 sysctl -p、sysctl -a、sysctl -w
    EM2 MP1 Vowel and Consonant Teacher:Ashley
    Phonics 自然拼读法 y,x,ch,sh,(voiced)th/ð/ ,(unvoiced) th/θ/ Teacher:Lamb
    java列表转成 int[] 的格式
    分类模型评估之ROC-AUC曲线和PRC曲线
    hive 抽样方法
    AUC理解
    Spark性能调优——基础篇
    scala 稀疏向量
    scala 建模
  • 原文地址:https://www.cnblogs.com/Scx117/p/9094677.html
Copyright © 2020-2023  润新知