The number of reverse order in the segment tree or tree array (with examples)

Source: Internet
Author: User

Learned blogger: Myzee, Shengweison's article

The number of reverse order in a segment tree or tree-like array


Suppose to give you a sequence 6 1 2 7 3 4 8 5, first we start to calculate the number of reverse, set the number of reverse order N;

In front of 6 there was no greater number N +=0 than he

In front of 1, there is a number larger than his n+=1

In front of 2, there is a number larger than his n+=1

In front of 7 there is no greater number than his n+=0

... Finally get N = 0 + 1 + 1 + 0 + 2 + 2 + 0 + 3 = 9


In fact, we can use a line tree, or a tree-like array to simulate this process. And because the line tree and tree array are more efficient, they are feasible


Let's say we put the sequence 6 1 2 7 3 4 8 5 into the array num "", num "1" =6, num "2" =1 ...

So each time, we can insert num "I" into a segment tree or a tree array, and assign a value of 1,

We sum sum,sum equal to the sum of 1 to num "I" in the line segment tree, then this sum represents a value that is currently smaller than the number of num "I";

At present, there is a total number of I, so the current is greater than num "I" is i-sum;

So we count all the i-sum, and they are the inverse number. Simulates the process of the above hand calculation.


"Key code for Segment tree"

<pre name= "code" class= "CPP" >int count=0;for (int i=1;i<=n;i++) {       insert (1,num[i],num[i],1);//Insert num[i] and is assigned a value of 1       count+= (i-(Query (1,1,num[i)));}

"Key code for a tree array"

Long Long  ans=0;for (int i=1;i<=n;i++) {Add (n[i].id); ans+= (I-sum (N[i].id));}

Of course, the ID of the number queried here is the default from 1 to N, if the number of questions required to enter more than this range, you need to use discretization,

This will be introduced in the following topic.


"Here is a number of reverse order for 1~n."

Segment Tree order number of reverse order # include <iostream> #include <cstdio> #include <cstring> #define L (a) A<<1#define R (a) (a<<1) |1const int maxn = 51000;int ans[maxn];struct node{int num,l,r;} Tree[maxn<<2];int n;void Build (int m,int l, int r) {tree[m].l=l;tree[m].r=r;if (TREE[M].L==TREE[M].R) {tree[m]. Num=0;return;} int mid = (TREE[M].L+TREE[M].R) >>1; Build (L (M), L,mid); Build (R (M), mid+1,r); Do not backtrack, create empty tree}void Insert (int m,int l,int r,int x) {if (tree[m].l==l&&tree[m].r==r) {tree[m].num+=x; return;} int mid = (TREE[M].L+TREE[M].R) >>1;if (r<=mid) Insert (L (m), l,r,x), else if (l>mid) Insert (R (m), l,r,x); else{ Insert (L (m), l,mid,x), insert (R (m), mid+1,r,x);} Tree[m].num=tree[l (M)].num+tree[r (m)].num;} int Query (int m,int l,int R) {if (tree[m].l==l&&tree[m].r==r) return tree[m].num;int mid = (TREE[M].L+TREE[M].R) >>1;if (R&LT;=MID) return query (L (m), l,r), if (l>mid) return query (R (m), l,r), return query (L (m), L,mid) +query (r (m), mid+1,r);} int main () {int a,n,i,t;scanf ("%d", &AMP;T); while (t--) {int k=0;scanf ("%d", &n); memset (tree,0,sizeof (tree)); Build (1,1,n), for (int i=1;i<=n;i++) {scanf ("%d", &ans[i]);} for (int i=1;i<=n;i++) {insert (1,ans[i],ans[i],1);//Insert 1k+= (I-query (1,1,ans[i)) at each location;} printf ("%d\n", k);} return 0;}

HDU 1394 to find the smallest value in multiple reverse order numbers

#include <iostream> #include <cstdio> #include <cstring> #define L (a) A<<1#define R (a) a<< 1|1using namespace Std;int n;const int maxn = 5005;int num[maxn];struct node{int l,r,sum;}    Tree[maxn<<2];void Build (int m,int l,int r) {tree[m].l=l; tree[m].r=r;        if (TREE[M].L==TREE[M].R) {//If the left and right nodes of the current node are the same, that is, the leaf node tree[m].sum=0;    return;    } int mid = (TREE[M].L+TREE[M].R) >>1;    Build (L (M), L,mid); Build (R (M), mid+1,r);        }void Insert (int m,int l,int r,int x) {if (tree[m].l==l&&tree[m].r==r) {tree[m].sum+=x;    return;    } int mid = (TREE[M].L+TREE[M].R) >>1;    if (mid>=r)//Here is greater than or equal to Insert (L (M), l,r,x);    else if (mid<l) Insert (R (M), l,r,x);        else{Insert (L (M), l,mid,x);    Insert (R (M), mid+1,r,x); } tree[m].sum=tree[l (M)].sum+tree[r (m)].sum;}    int Query (int m,int l,int R) {if (tree[m].l==l&&tree[m].r==r) {return tree[m].sum; } int mid = (tree[m].l+trEE[M].R) >>1;    Here is the same as Insert if (mid>=r) return Query (L (M), l,r);    if (mid<l) return Query (R (M), l,r); Return Query (L (M), L,mid) +query (R (M), mid+1,r);}        int main () {while (scanf ("%d", &n)!=eof) {memset (tree,0,sizeof (tree));        Build (1,1,n);            for (int i=1;i<=n;i++) {scanf ("%d", &num[i]);        num[i]++;        } int count=0;            for (int i=1;i<=n;i++) {Insert (1,num[i],num[i],1);        count+= (I-(Query (1,1,num[i)));        } int ans = count;            for (int i=1;i<=n;i++) {num[i]--;            Count = count-num[i]*2 + n-1;        if (count<ans) ans = count;    } printf ("%d\n", ans); } return 0;}

NYOJ 117 seeking reverse order number

This needs to be discretized,

Create a struct containing Val and ID, Val is the number of inputs, ID indicates the order of input. Then according to Val from small to large sort, if Val is equal, then sort by ID.

If there is no reverse order, I am sure ID is the same as I (the sequence after the shoot) has been the same, if there are reverse number, then some I and ID is not the same. So, using the characteristics of a tree array, we can simply calculate the number of reverse order numbers.

If you still don't understand, give me an example. (Enter 4 numbers)

Input: 9-1 18 5

Output 3.

The corresponding structure will become the same after the input.

Val:9-1 18 5

Id:1 2 3 4

After the sequence, it becomes

Val:-1 5 9 18

Id:2 4 1 3

2 4 1 3 The reverse number is also 3

Then we can solve the problem by using the characteristics of the tree array.


Because the number may be duplicated, so the addition operation is no longer purely 1, but + +;

"Source Code"

#include <iostream> #include <cstdio> #include <algorithm> #include <cstring>using namespace Std;int n;const int maxn = 1000005;struct node{int val,id;} N[maxn];int c[maxn];int CMP (const node &a,const node& b) {if (a.val==b.val) return A.id<b.id;return a.val< B.val;} int lowbit (int x) {return x& (-X);} void Add (int x) {while (x<=n) {c[x]++;//may have duplicates because with + + does not use = 1;x+=lowbit (x);} return;} int Sum (int x) {int ans = 0;while (x>0) {ans+=c[x];x-=lowbit (x);} return ans;} int main () {int t;scanf ("%d", &t), while (t--) {scanf ("%d", &n), and for (int i=1;i<=n;i++) {scanf ("%d", &n[i]. Val); N[i].id=i;} Sort (n+1,n+n+1,cmp);//Sort memset from 1-n (c,0,sizeof (c)); Do not forget to initialize long long  ans=0;//int  will explode for (int i=1;i<=n;i++) {Add (n[i].id); ans+= (I-sum (N[i].id));} printf ("%lld\n", ans);} return 0;}        







Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.

The number of reverse order in the segment tree or tree array (with examples)

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.