HYSBZ - 3289 Mato's file management MOTU algorithm + tree array

Title Link: https://cn.vjudge.net/problem/HYSBZ-3289

Mato collected a lot of data from all kinds of gods in various ways (you know), and there were n copies of these data, each with a size and a number

. In order to prevent others from copying, these materials are encrypted and can only be accessed by the program written by Mato himself. Mato randomly selects an interval every day [l,r

]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'll see first

The files are copied out in order of number, and then the file size is sorted by the sorting program written by him. The sorter can exchange two adjacent

File (cannot be accessed randomly because of encryption requirements). 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 line q has two positive integers L and r in each line, indicating the files in the interval of [l,r] that Mato looks at on that day.

n,q <= 50000

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 / / sample explanation: on the first day, Mato does not need to exchange the second day. Mato can move the exchange 2 to the end twice.

When operating on the left side, the query is larger than others. When operating on the right side, the query is smaller than others. Pay attention to discretization.

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define lowbit(x) x&(-x)
const int N=50010;
struct node{
	int l,r;
	int id;
}a[N];
int n,m,CM;
int c[N],b[N];
int sum1[N];// xiao
int sum2[N];// da
ll ans[N];
bool cmp(node x,node y)
{
	if(x.l/CM!=y.l/CM) return x.l<y.l;
	else return x.r<y.r;
}
void update1(int x,int val)
{
	while(x<=n)
	{
		sum1[x]+=val;
		x+=lowbit(x);
	}
}
int query1(int x)
{
	int res=0;
	while(x)
	{
		res+=sum1[x];
		x-=lowbit(x);
	}
	return res;
}
void update2(int x,int val)
{
	while(x)
	{
		sum2[x]+=val;
		x-=lowbit(x);
	}
}
int query2(int x)
{
	int res=0;
	while(x<=n)
	{
		res+=sum2[x];
		x+=lowbit(x);
	}
	return res;
}
int main()
{
	while(scanf("%d",&n)!=EOF)
	{
	//	scanf("%d",&n);
		
		for(int i=1;i<=n;i++)scanf("%d",&c[i]),b[i]=c[i];
		sort(b+1,b+1+n);
		int len=unique(b+1,b+1+n)-(b+1);
		CM=(int)sqrt(n); 
		for(int i=1;i<=n;i++)
		{
			c[i]=lower_bound(b+1,b+1+len,c[i])-b;
		}
		scanf("%d",&m);
		for(int i=1;i<=m;i++)scanf("%d%d",&a[i].l,&a[i].r),a[i].id=i;
		sort(a+1,a+1+m,cmp);
		int l,r;
		ll res;
		for(int i=1,j=1;j<=m;i++)
		{
			memset(sum1,0,sizeof(sum1));
			memset(sum2,0,sizeof(sum2));
			l=a[j].l+1,r=a[j].l;
			res=0;
			for(;j<i*CM && j<=m;j++)
			{
				while(a[j].l<l)
				{
					l--;
					res+=query1(c[l]-1);
					update1(c[l],1);
					update2(c[l],1);
				}
				while(a[j].l>l)
				{
					res-=query1(c[l]-1);
					update1(c[l],-1);
					update2(c[l],-1);
					l++;
				}
				
				while(a[j].r<r)
				{
					res-=query2(c[r]+1);
					update1(c[r],-1);
					update2(c[r],-1);
					r--;
				}
				while(a[j].r>r)
				{
					r++;
					res+=query2(c[r]+1);
					update1(c[r],1);
					update2(c[r],1);
				}
				ans[a[j].id]=res;
				l=a[j].l,r=a[j].r;
			}
		}
		for(int i=1;i<=m;i++)
		{
			printf("%lld\n",ans[i]);	
		}
	}
	
	return 0;
}

 

Posted on Sun, 10 Nov 2019 13:45:05 -0500 by Dunoon