Description
For sequence A, its inverse logarithm is defined to satisfy the I < J, and AI > The number of AJ's pairs (i,j). An arrangement of 1 to N, in which the M elements are removed sequentially, your task is to count the inverse logarithm of the entire sequence before deleting one element at a time.
Input
Enter the first line containing two integers n and M, that is, the number of initial elements and the number of deleted elements. The following n rows each row contains a positive integer between 1 and N, which is the initial arrangement. The following M-line is a positive integer for each row, followed by each deleted element.
Output
The output contains m rows, followed by the number of reverse pairs before each element is deleted.
Sample Input
5 4
1
5
3
4
2
5
1
4
2
Sample Output
5
2
2
1
Sample explanation
(1,5,3,4,2)? (1,3,4,2)? (3,4,2)? (3,2)? (3).
HINT
N ≤ 100000 M ≤ 50000
Source
It's so easy to cdq this problem. www.
It is said that the chairman of the tree will be stuck constant CDQ completely not worried
A tree-like array is used to preprocess the number of inverse pairs in the initial sequence, including the number of inverse pairs corresponding to each digit.
Then open an array called NEW_INV, which is used to record the number of reverse pairs of sequences that have been deleted (because if you subtract the inverse of each number directly in ans, there are some reverse pairs that will be repeated)
Then start the bare CDQ division operation on it.
By the way, this is the first time I've used a tree-like array to reverse-order. Admire POPOQQQ god Ben >ω< get a simple tree-like array function from him (because I'm just going to use a tree array for two or three days →_← don't ask me why I just learned the tree-like array because I'm sandy tea 233)
For a tree-like array, reverse-order:
In fact, it's equivalent to inserting those numbers into a tree-like array one at a time to see how much smaller the number is when inserting it in.
Specifically, you can read this article
AC Code by Creationaugust#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <algorithm>#define MAXN 101000#define LBT (x) (x&-x)//drag operator precedence = = Do not add () will bombusing namespace Std;intNm; Long long ans;intTotintA[MAXN],B[MAXN];//Used for tree-like array statistics in reverse orderintNEW_INV[MAXN];//Represents the number of reverse pairs in a sequence of deleted elements after an element has been deletedintTim[maxn];struct query{intNumPOS;//numFor the number of deletions,POSThe location for Num to appear,xThe time for the operation to occurint x; BOOL operator < (const query& a) const{return POS<a.POS; }}ques[maxn],newQ[MAXN];intC[MAXN];intNum[maxn];void Modify (intIintFlag)//This writing changes the downward and upward modifications together { for(;i>0&&I<=N;I+=LBT (i)*flag) {if(Tim[i]!=tot) c[i]=0, Tim[i]=tot; c[i]++; }}intSumintIintFlag)//Ibid, two queries pressed together {intret=0; for(;i>0&&I<=N;I+=LBT (i)*flag)if(Tim[i]==tot) ret+=c[i];returnRET;} void Solve (intLintR) {intMid= (l+r) >>1, tp1=l,tp2=mid+1;if(L==R) {printf("%lld\ n", ans); ANS-=NUM[QUES[L].POS]; ANS+=NEW_INV[L];//Because if you simply delete, a reversed pair will be deleted two times//So we have to add the deletion of it after the action sequence in the new reverse orderreturn; } for(inti=l;i<=r;i++)//By Time Division operationif(Ques[i].x<=mid) Newq[tp1++]=ques[i];ElseNewq[tp2++]=ques[i]; memcpy (ques+l,newq+l,sizeof (Query)*(r-l+1)); Solve (L,mid); tot++;intJ=l; for(intI=mid+1i<=r;i++)//update new appearing reverse order { for(; J<=mid&&ques[j].POS<ques[i].POS; j + +) modify (ques[j].num,-1); New_inv[ques[i].x]+=sum (Ques[i].num,1); } tot++; J=mid; for(intI=r;i>=mid+1; i--) { for(; J>=l&&ques[j].POS>ques[i].POS; j--) Modify (Ques[j].num,1); New_inv[ques[i].x]+=sum (ques[i].num,-1); } Solve (mid+1, R);//The remainder of the operation is still sorted in the order of the previous keywords tp1=l,tp2=mid+1; for(inti=l;i<=r;i++)if((ques[tp1]<ques[tp2]| | TP2>R) &&tp1<=mid) NewQ[i]=ques[tp1++];ElseNewQ[i]=ques[tp2++]; memcpy (ques+l,newq+l,sizeof (Query)*(r-l+1));}intMain () {Freopen ("Inverse.in","R", stdin); Freopen ("Inverse.out","W", stdout); scanf"%d%d",&n,&m);//The tree-like array to find out the initial reverse for(intI=1; i<=n;i++) scanf ("%d", &a[i]), b[a[i]]=i; for(intI=1; i<=n;i++) {num[i]=sum (A[i],1); Modify (a[i],-1); Ans+=num[i]; } ++tot; for(inti=n;i>=1; i--) {Num[i]+=sum (a[i],-1); Modify (A[i],1); } for(intI=1; i<=m; i++) {scanf ("%d", &ques[i].num); Ques[i].POS=b[ques[i].num]; Ques[i].x=i; }Sort(ques+1, ques+m+1);//The entire sequence of operations is pressedPOSKeyword sort solve (1,m);}
"CQOI2011" "BZOJ3295" dynamic reverse order