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 }

 

转载于:https://www.cnblogs.com/tang666/p/8866047.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值