[bzoj3289] Mato's document management

Description

Mato collected a lot of information from all kinds of gods in various ways (you know). There are n copies of the information, each with a size and a number. In order to prevent others from copying, these materials are encrypted, and can only be accessed by programs written by Mato himself. Mato randomly selects a range [l,r] every day, and today he looks at the data numbered in this range. Mato has a habit of looking at data from small to large file sizes. He first copies the documents to be viewed in order of number, and then sorts the size of the documents by the sorting program he wrote. The sorter can exchange 2 adjacent files in 1 unit time (because of encryption requirements, random access is not allowed). If Mato wants to minimize the number of file exchanges, can you tell him how many times a day he needs to exchange?

Input

The first line is a positive integer n, indicating the number of copies of Mato's data.
The second line is n positive integers separated by spaces, and the i represents the size of the data numbered i.
In the third line, a positive integer q indicates that Mato will look at the data for a few days.
Then, two positive integers L and r in each line of line q indicate the files in the [l,r] range that Mato looks at on that day.

Output

Line q, a positive integer in each line, indicates the number of times that Mato needs to exchange on this day.

Sample Input

4

1 4 2 3

2

1 2

2 4

Sample Output

0

2

HINT

Hint

n,q <= 50000

Example explanation: on day one, Mato does not need to exchange

The next day, Mato can move exchange 2 twice to the end.

Title Solution
Mo team + tree array.

Code

#include<bits/stdc++.h>
#define ll long long
#define inf 1000000000
#define mod 1000000007
using namespace std;
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
unsigned int ans;
int n,m,L,R,block;
int a[50005],t[50005],ls[50005];
struct node{int l,r,id,bl;unsigned ans;}q[50005];
inline bool cmp(node a,node b){return (a.bl!=b.bl)?a.bl<b.bl:a.r<b.r;}
void add(int x,int val)
{
    for(int i=x;i<=n;i+=i&-i)
        t[i]+=val;
}
unsigned int query(int x)
{
    unsigned int sum=0;
    for(int i=x;i;i-=i&-i)
        sum+=t[i];
    return sum;
}
void solve()
{
    L=1;R=0;
    for (int i=1;i<=m;i++)
    {
        while (L<q[i].l){add(a[L],-1);ans-=query(a[L]-1);L++;}
        while (L>q[i].l){L--;add(a[L],1);ans+=query(a[L]-1);}
        while (R<q[i].r){R++;add(a[R],1);ans+=R-L+1-query(a[R]);}
        while (R>q[i].r){add(a[R],-1);ans-=R-L-query(a[R]);R--;}
        q[q[i].id].ans=ans;
    }

}
int main()
{
    n=read();block=sqrt(n);
    for(int i=1;i<=n;i++)ls[i]=a[i]=read();
    sort(ls+1,ls+n+1);
    for(int i=1;i<=n;i++)a[i]=lower_bound(ls+1,ls+n+1,a[i])-ls;
    m=read();
    for (int i=1;i<=m;i++)
    {
        q[i].l=read();q[i].r=read();
        q[i].bl=(q[i].l-1)/block+1;q[i].id=i;
    }
    sort(q+1,q+m+1,cmp);
    solve();
    for (int i=1;i<=m;i++) printf("%d\n",q[i].ans);
    return 0;
}

Posted on Sun, 03 May 2020 06:36:09 -0400 by tecktalkcm0391