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/ +
+++++++++++++++++++++++++++++++++++++++++++