zoukankan      html  css  js  c++  java
  • BZOJ 3192: [JLOI2013]删除物品(树状数组)

    题面:

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

    题解:
      首先每次一定是来回移动直到最大的到顶上。

      所以我们可以将第两个堆的堆顶接起来形成一个队列。

      然后相当于中间一个象征两堆分界的指针在来回移动。

      用树状数组维护一下区间内删除了几个点。

    代码:

     1 #include<bits/stdc++.h>
     2 
     3 using namespace std;
     4 
     5 typedef long long ll;
     6 const int maxn=100010;
     7 ll ans,n,m,tr[maxn],mx;
     8 
     9 struct node{
    10     ll w,pos;
    11     bool operator < (const node &b)    const{
    12         return w>b.w;
    13     }
    14 }f[maxn];
    15 
    16 ll lowbit(ll x){
    17     return x&-x;    
    18 }
    19 
    20 void add(ll k,ll x){
    21     for(int i=k;i<=mx;i+=lowbit(i))
    22         tr[i]+=x;    
    23 }
    24 
    25 ll ask(int k){
    26     int sum=0;
    27     for(int i=k;i;i-=lowbit(i))
    28         sum+=tr[i];
    29     return sum;
    30 }
    31 
    32 int main(){
    33     scanf("%d%d",&n,&m);mx=n+m;
    34     for(int i=1;i<=n;i++) scanf("%lld",&f[n-i+1].w),f[n-i+1].pos=n-i+1;
    35     for(int i=1;i<=m;i++) scanf("%lld",&f[n+i].w),f[n+i].pos=n+i;
    36     sort(f+1,f+n+m+1);ll tt=n;
    37     for(int i=1;i<=mx;i++){
    38         if(tt>=f[i].pos) ans+=tt-f[i].pos-(ask(tt)-ask(f[i].pos)),tt=f[i].pos;    
    39         else ans+=f[i].pos-tt-1-(ask(f[i].pos)-ask(tt)),tt=f[i].pos-1;
    40         add(f[i].pos,1);
    41     }
    42     printf("%lld",ans);
    43     return 0;    
    44 }
  • 相关阅读:
    JVM基础
    JVM基础
    python相关
    charles 的配置与使用
    大型缓存架构实战
    redis环境搭建
    多线程与并发 | 线程池
    JVM | 内存溢出和解决方案
    读书笔记 | Mysql是怎样运行的
    读书笔记 | Java并发编程实战
  • 原文地址:https://www.cnblogs.com/tang666/p/8866047.html
Copyright © 2011-2022 走看看