BZOJ3192:[JLOI2013]刪除物品——題解

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

箱子再分配問題須要解決以下問題:node

(1)一共有N個物品,堆成M堆。ios

(2)全部物品都是同樣的,可是它們有不一樣的優先級。git

(3)你只可以移動某堆中位於頂端的物品。數組

(4)你能夠把任意一堆中位於頂端的物品移動到其它某堆的頂端。若此物品是當前全部物品中優先級最高的,能夠直接將之刪除而不用移動。spa

(5)求出將全部物品刪除所需的最小步數。刪除操做不計入步數之中。code

(6)只是一個比較難解決的問題,這裏你只須要解決一個比較簡單的版本: 不會有兩個物品有着相同的優先級,且M=2blog

水題,注意開longlong。get

把兩個棧口對口連上,而後每次記錄當前的棧口在哪兩個元素之間,按照元素大小順序依次找要被刪掉的數的位置,以後就分類討論便可。博客

注意記錄一下哪些位置的數被刪掉了就好,樹狀數組維護便可。

#include<map>
#include<cmath>
#include<stack>
#include<queue>
#include<cstdio>
#include<cctype>
#include<vector>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=2e5+5;
inline int read(){
    int X=0,w=0;char ch=0;
    while(!isdigit(ch)){w|=ch=='-';ch=getchar();}
    while(isdigit(ch))X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
    return w?-X:X;
}
struct node{
    int x,y;
}b[N];
int n,m,a[N],tr[N];
inline bool cmp(node a,node b){
    return a.x>b.x;
}
inline int lowbit(int t){return t&-t;}
inline void add(int x,int y){
    for(int i=x;i<=n;i+=lowbit(i))tr[i]+=y;
}
inline int ask(int x){
    int res=0;
    for(int i=x;i;i-=lowbit(i))res+=tr[i];
    return res;
}
int main(){
    n=read(),m=read();
    for(int i=n;i>=1;i--){
        a[i]=b[i].x=read();
        b[i].y=i;
    }
    for(int i=n+1;i<=n+m;i++){
        a[i]=b[i].x=read();
        b[i].y=i;
    }
    int l=n;ll ans=0;n+=m;
    sort(b+1,b+n+1,cmp);
    for(int i=1;i<=n;i++){
        int t=b[i].y;
        if(t<=l){
            ans+=l-t-ask(l)+ask(t-1);
        }else{
            ans+=t-l-ask(t)+ask(l)-1;
        }
        l=t-1;
        add(t,1);
    }
    printf("%lld\n",ans);
    return 0;
}

+++++++++++++++++++++++++++++++++++++++++++

+本文做者:luyouqi233。               +

+歡迎訪問個人博客:http://www.cnblogs.com/luyouqi233/ +

+++++++++++++++++++++++++++++++++++++++++++

相關文章
相關標籤/搜索