This blog is about square root decomposition.
Here we divide the entire elements into k parts such that each part has root(n) elements. In this manner only the last part will have <=root(n) elements. Now each query can be said to be connecting three regions the first part of the range that doesnot lie completely in a interval the next part that lies in a interval totally and the next that doesnot lie totally
Suppose we have an array of 11 element
then the groups are (1) 1-3 (2) 4-6 (3) 7-9 (4) 10-11
Thus there are three groups of root(11) size and the last one contains 2 elements.
Suppose we want to obtain the sum of elements from 2 to 10
this can be done as arr[2]+arr[3]+sumofgroup(2)+sumofgroup(3)+arr[10]
It can be shown that the maximum complexity is 3root(n) and this tool is quite important
Here is a question (RMQ) solved using square root decomposition
Here we divide the entire elements into k parts such that each part has root(n) elements. In this manner only the last part will have <=root(n) elements. Now each query can be said to be connecting three regions the first part of the range that doesnot lie completely in a interval the next part that lies in a interval totally and the next that doesnot lie totally
Suppose we have an array of 11 element
then the groups are (1) 1-3 (2) 4-6 (3) 7-9 (4) 10-11
Thus there are three groups of root(11) size and the last one contains 2 elements.
Suppose we want to obtain the sum of elements from 2 to 10
this can be done as arr[2]+arr[3]+sumofgroup(2)+sumofgroup(3)+arr[10]
It can be shown that the maximum complexity is 3root(n) and this tool is quite important
Here is a question (RMQ) solved using square root decomposition
RMQSQ - Range Minimum Query
no tags
You are given a list of N numbers and Q queries. Each query is specified by two numbers i and j; the answer to each query is the minimum number between the range [i, j] (inclusive).
Note: the query ranges are specified using 0-based indexing.
Note: the query ranges are specified using 0-based indexing.
Input
The first line contains N, the number of integers in our list (N <= 100,000). The next line holds N numbers that are guaranteed to fit inside an integer. Following the list is a number Q (Q <= 10,000). The next Q lines each contain two numbers i and j which specify a query you must answer (0 <= i, j <= N-1).Output
For each query, output the answer to that query on its own line in the order the queries were made.Example
Input: 3 1 4 1 2 1 1 1 2
Output: 4 1
The code runs here!!!!
#include<iostream>
#include<stdio.h>
#include<bits/stdc++.h>
using namespace std;
long long int inp[100010];
long long int arr[100010];
int n;
#include<math.h>
void build(int k)
{
// cout<<"in build "<<endl;
for(int i=0;i<n;i++)
{
// cout<<i/k<<" "<<i<<endl;
arr[i/k]=min(inp[i],arr[i/k]);
}
}
long long int query(int low, int high,int k)
{
long long int minval=INT_MAX;
int i=low;
//cout<<low<<" "<<high<<endl;
while(i%k!=0 && i<=high)
{
minval=min(minval,inp[i]);
// cout<<"int part 1 "<<i<<" "<<endl;
i++;
}
while(i+k<=high)
{
minval=min(minval,arr[i/k]);
// cout<<"int part 2 "<<i<<" "<<endl;
i+=k;
}
while(i<=high)
{
minval=min(minval,inp[i]);
// cout<<"int part 3 "<<i<<" "<<endl;
i+=1;
}
return minval;
}
int main()
{
cin>>n;
for(int i=0;i<n;i++)
{
scanf("%lld",&inp[i]);
}
int k=sqrt(n);
for(int i=0;i<k+10;i++)
arr[i]=INT_MAX;
build(k);
int q;
cin>>q;
int l,r;
while(q--)
{
//cin>>l>>r;
scanf("%d",&l);
scanf("%d",&r);
long long int ans=query(l,r,k);
printf("%lld\n",ans);
}
return 0;
}
Related links and stuffs!!!
http://www.infoarena.ro/blog/square-root-trick
Blog by anudeep on MO algorithm
No comments:
Post a Comment