mouseover(滑鼠覆蓋)與 mouseenter(滑鼠進入) mouseout和mouseleave的區別以及阻止冒泡的方法
阿新 • • 發佈:2020-09-11
題目連結:https://vjudge.net/problem/POJ-2182
題意:n頭牛,身高為1到n的一個排列。已知每頭牛前面比它矮的個數,求每頭牛的身高
這題和習題裡的poj2828基本一樣。倒著考慮,如果最後一頭牛前面有k1個比它矮,那麼它的身高就是k1+1。倒數第二頭如果有k2個比它矮,那麼它的身高是一個數(不等於k1+1),且滿足:比它小的而且沒出現過的數的個數為k2。等價於需要維護一個01序列,要求支援把1變成0的操作(是否出現過);求出一個數,它的字首和為某個值(有多少個數比當前的小)。單點修改和求字首和可以用樹狀陣列,快速求出這個數的位置用二分即可
#include<cstdio> using namespace std; const int N=8000+10; int c[N],a[N],res[N],b[N],n,i,j,k,l,r; void add(int x,int y){ for (int i=x;i<=n;i+=i&(-i)) c[i]+=y; } int ask(int x){ int res=0; for (int i=x;i>0;i-=i&(-i)) res+=c[i]; return res; } int main(){ scanf("%d",&n); for (i=1;i<=n;i++) add(i,1); for (i=2;i<=n;i++) scanf("%d",&a[i]); for (i=n;i>=2;i--){ l=0; r=n; while (r-l>1){ int m=(l+r)/2; if (ask(m)<a[i]+1) l=m; else r=m; //* } res[i]=r; b[r]=1; add(r,-1); } for (i=1;i<=n;i++) if (!b[i]) res[1]=i; for (i=1;i<=n;i++) printf("%d\n",res[i]); return 0; }