"Original title"
3333: Line plan time limit: Sec Memory Limit: MB
Submit: 161 Solved: 71
[Submit] [Status] Description
Input
Output
Sample Input6 2
160 163 164 161 167 160
2
3Sample Output6
3
1
HINT
Source
wyx528 Proposition
"Analysis" briefly describes the topic. n the number of rows in a column. Each time you specify a position p, and then put all the p~n in the height of the person is equal to the P is carried out, order and then put in. Each operation must be ordered in reverse order.
First, very easy to think: each time a position p is selected, the reduced reverse order is the number of the p~n to meet the requirements of the original form of reverse--and when the operation is complete. These people will never have a reverse order.
Given this nature, we are able to maintain a number of f[i], which indicates the number of reverse orders starting from the position of I. (We don't care what the value is at a certain point in a location) and then we use a segment tree to maintain the minimum value in the i~n. Each operation looks for the minimum value of p~n. Assuming that the requirements are met and the position is x, then we set the f[x] to 0, and then we can set the number of x positions to infinity. Then continue looking until you can't find it. Since each number is only updated at most, efficiency averaging is nlogn.
Code
#include <cstdio> #include <algorithm> #define N 500005#define INF 1000000005#define Lo (x) (x&-x) using Namespace Std;typedef long long LL; LL ans=0;struct tree{int L,r,min,wh;} A[n*3];int Tree[n];//pos p in array to the Treeint pos[n*4];//pos p int tree to the Arrayint f[n],data[n],c[n],n,cnt,x,i,o Pt,p,ord,size,now,l,r;struct array{int X,id;} Uni[n];inline int cmp (const array &a,const array &b) {return a.x<b.x;} inline int Ask (int x) {int s=0;for (; X;x-=lo (x)) S+=c[x];return s;} inline void Add (int x) {for (; X<=n;x+=lo (x)) c[x]++;} void build (int k,int l,int r) {a[k].l=l;a[k].r=r; if (l==r) {a[k].min=data[l];p Os[k]=l;tree[l]=k;a[k].wh=k;return;} int mid= (L+R) >>1; if (l<=mid) build (K<<1,l,mid); if (r>mid) build (K<<1|1,MID+1,R); if (a[k<<1].min<a[k<<1|1].min) a[k].min=a[k<<1].min,a[k].wh=a[k<<1].wh; else A[K].MIN=A[K<<1|1].MIN,A[K].WH=A[K<<1|1].WH;} int query (int k) {if (l<=a[k].l&&a[k].r< =r) return a[k].wh; int mid= (A[K].L+A[K].R) >>1,resl=0,resr=0; if (l<=mid) resl=query (k<<1); if (r>mid) resr=query (k<<1|1); if (!RESL) return resr;if (!RESR) return resl; Return (a[resl].min<a[resr].min)?RESL:RESR;} void update (int k) {if (A[K].L==A[K].R) {A[k].min=inf;a[k].wh=k;return;} int mid= (A[K].L+A[K].R) >>1; if (ord<=mid) update (k<<1); else update (K<<1|1); if (a[k<<1].min<a[k<<1|1].min) a[k].min=a[k<<1].min,a[k].wh=a[k<<1].wh; else a[k].min=a[k<<1|1].min,a[k].wh=a[k<<1|1].wh; }int Main () {read (n); read (opt);//read-in optimization omit for (i=1;i<=n;i++) read (x), uni[i]= (array) {x,i}; Sort (uni+1,uni+n+1,cmp); for (i=1;i<=n;i++) data[uni[i].id]= (uni[i].x==uni[i-1].x)? cnt:++cnt; for (i=n;i;i--) F[i]=ask (data[i]-1), add (Data[i]), ans+= (LL) f[i]; Build (1,1,n);p rintf ("%lld\n", ans); while (opt--) {read (P); now=a[tree[p]].min; while (Now<inf) {l=p; R=n;ord=query (1); size=a[ord].min; if (Size>now) Break;ord=pos[ord]; ans-= (LL) f[ord];f[ord]=0;update (1); } printf ("%lld\n", ans); } return 0;}
Copyright notice: This article Bo Master original articles, blogs, without consent may not be reproduced.
Bzoj 3333: Queuing plans to solve problems