n number, to find a reverse order. Then there are m modification operations, the number of each input position p after <= its number out, from small to large after the order back to the empty space, for reverse. (n,m<=500,000, Ai<=10^9)
Ideas:
1. Modify it later to save the suffix instead of the generic prefix. The number of <= is s[i] After the save number I, which is used for subsequent reverse order.
2. When the number of changes is sorted, their s[] are zeroed, or they can be "erased"-changing their value to INF.
Realize:
1. Use a tree-like array (or segment tree) to find the initial inverse logarithm sum.
2. Each operation uses a segment tree to find the number of all <= in the p to n interval, by finding the smallest number, sum minus its s[] value, and changing its value to inf for "delete".
3. The number of the minimum number of weights in the segment tree, so that it is convenient to find it directly. Do not worry about a time-out, because "delete" will not find it, for O (n), the smallest number is O (log n), the entire program is O (n log n) time complexity.
1#include <cstdio>2#include <cstdlib>3#include <cstring>4#include <iostream>5#include <algorithm>6 using namespacestd;7typedefLong LongLL;8 9 ConstLL n=500010, inf= (LL) 1e9+ -;Ten LL n,m; One LL B[n],s[n],c[n]; A structNode{ll L,r,lc,rc,id;} a[n*2]; -LL len=0; - structhp{ll x,t;} E[n]; the - ll Mmin (ll X,ll y) -{returnX<y?x:y; } - ll CP (ll X,ll y) +{returnB[x]<b[y]?x:y; } - + voidbt (LL l,ll R) A { atLL x=++Len; -A[x].l=l,a[x].r=R; -a[x].lc=a[x].rc=-1; - if(l==r) a[x].id=l; - ElseA[x].id=0; - if(l<R) in { -LL mid= (l+r)/2; toa[x].lc=len+1, Bt (L,MID); +a[x].rc=len+1, Bt (mid+1, R); - theLL lc=a[x].lc,rc=a[x].rc; *A[x].id=CP (a[lc].id,a[rc].id); $ }Panax Notoginseng } - voidChange (LL x,ll p,ll ID) the { + if(A[X].L==A[X].R) {a[x].id=n+1;return;} ALL lc=a[x].lc,rc=a[x].rc,mid= (A[X].L+A[X].R)/2; the if(p<=mid) Change (lc,p,id); + ElseChange (rc,p,id); -A[x].id=CP (a[lc].id,a[rc].id); $ } $ ll Getmin (ll x,ll l,ll R) - { - if(A[X].L==L&&A[X].R==R)returna[x].id; theLL lc=a[x].lc,rc=a[x].rc,mid= (A[X].L+A[X].R)/2; - if(R<=mid)returngetmin (lc,l,r);Wuyi if(L>mid)returngetmin (rc,l,r); the returnCP (Getmin (LC,L,MID), Getmin (rc,mid+1, R)); - } Wu - BOOLCMP (HP U,HP v) About{returnu.x<v.x; } $ -ll Lowbit (ll x) {returnx&-x;} - ll S (ll x) - { ALL h=0; + for(LL i=x;i>=1; i-=lowbit (i)) theh+=C[i]; - returnh; $ } the voidC (LL x) the{ for(LL i=x;i<=n;i+=lowbit (i)) c[i]++; } the the intMain () - { inscanf"%i64d%i64d",&n,&m); the for(LL i=1; i<=n;i++) thescanf"%i64d", &e[i].x), e[i].t=i; AboutSort (e+1, e+1+n,cmp); theLL x=0; thee[0].x=INF; the for(LL i=1; i<=n;i++) + { - if(e[i].x!=e[i-1].x) x + +; theb[e[i].t]=x;Bayi } theb[n+1]=INF; theLL sum=0; -Memset (c,0,sizeof(c)); - for(LL i=n;i>=1; i--) the { theS[i]=s (b[i]-1); thesum+=S[i]; the C (B[i]); - } theprintf"%i64d\n", sum); theBt1, n); the while(m--)94 { the LL p; thescanf"%i64d",&p); theLL T=b[p],k=getmin (1, p,n), h=0;98 while(b[k]<=t) About { -H+=S[K];//101Change1, k,n+1);102K=getmin (1, p,n);103 }104sum-=h; theprintf"%i64d\n", sum);106 }107 return 0;108}
"Bzoj 3333" queue plan (line segment tree)