It was a long time ago when I foolishly looked at strange sources of information and was knocked out by all sorts of Manhattan.
and Now we're going to learn the Chunking method. Another new creation of a chunking method.
Let's consider such an interval to ask questions ...
It has the following properties:
0,n number, q a query.
1, it has no modification operation, which means we can play with the inquiry in the order we like. we can actually play in any order.
2, we can easily find the values of [l±1, R] and [L, r±1] if we know the value of the interval asking [L, R].
(In fact, if the limit increases, such as only the value of [L+1, R] and [L, R-1], the same does not affect the resolution of the problem--This is my mouth, not written, and later. I don't know what it's like in the traditional team, it works in the new algorithm. )
3, if the 2 operation corresponds to the complexity of P, and you need to use O (p*n^1.5)(obviously) O (p*n*q^0.5) complexity to solve the problem, then the MO team algorithm is what you need.
Offline Method: The n number is divided into sqrt (n) blocks (a bunch of people who say what mentality) sqrt (Q) block
The query is sorted by interval, with the block ordinal of L as the first keyword, and r as the second keyword, to sort. (Traditional team is so pointers, yy a bit good)
But do not know how this practice spread open, feel no merit? Especially the complexity is so misleading really good.
Most of this type of interval Q is always greater than n (much larger!). ...... )。 Then the right Manhattan tree to find the worst is n*sqrt (m), chunking can also do this complexity, but no brain block directly into the M*SQRT (n) ...
One day you will be out of touch with your race to Kaguang you ...
(
But then again ... SQRT (n) blocks in random data seem to be faster ...
The random data is obviously the bigger the block the better ...
)
First say "Spoj3267:d-query", after all, is to do this way.
But you can use MO team A This problem is not much.
Title Descriptionthere is a sequence of n integers a1,a2,a3,,an. Existing q query, each inquiry will give two number i,j. Please give the number of different numbers in the interval of number I to number J of the series. input
First line: An integer nthat represents the length of the sequence.
Second line:n integers A1,A2,A3, ..., an(1 <= ai <= 10^6), The number and number are separated by a space.
Third line: An integer q (<= 200000)that indicates the number of queries.
Next Q line, two integers per line i,J(1 <= i <= j <= N <= 30000), indicates the interval to ask.
Output
For each query, output the number of different numbers within this interval.
Sample Input51 1 2) 1 331 52 43 5Sample Output323
No special.
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
using
namespace
std;
#define rep(i,j,n) for(int i=j;i<=n;i++)
char
c;
template
<
class
T>
inline
void
read(T&x){
for
(c=
getchar
();c<
‘0‘
||c>
‘9‘
;c=
getchar
());
for
(x=0;c>=
‘0‘
&&c<=
‘9‘
;c=
getchar
())x=x*10+c-
‘0‘
;};
struct
E{
int
x,y,l,list;}d[200010];
int
next[30010],prev[30010],p[1000010],ans[200010];
int
n,nn,x,T;
bool
cmp(E x,E y){
return
x.l<y.l||(x.l==y.l&&x.y<y.y);}
int
main(){
read(n);
memset
(next,63,n<<2);
rep(i,1,n){
read(x);
if
(!p[x])p[x]=i;
else
prev[i]=p[x],next[p[x]]=i,p[x]=i;
}
read(T);nn=
int
(
sqrt
(n));//块长……理论上的话……改成n/sqrt
(m)比较好
rep(i,1,T){read(d[i].x);read(d[i].y);d[i].l=(d[i].x+nn-1)/nn;d[i].list=i;}
sort(d+1,d+T+1,cmp);
int
ll,lr,now;
rep(ii,1,T){
if
(d[ii].l!=d[ii-1].l){
now=0;
rep(i,d[ii].x,d[ii].y)
if
(prev[i]<d[ii].x) now++;
ans[d[ii].list]=now;
}
else
{
if
(d[ii-1].x<d[ii].x){
ll=d[ii-1].x;lr=d[ii].x-1;
rep(i,ll,lr)
if
(next[i]>d[ii-1].y) now--;
}
else
{
ll=d[ii].x;lr=d[ii-1].x-1;
rep(i,ll,lr)
if
(next[i]>d[ii-1].y) now++;
}
ll=d[ii-1].y+1;lr=d[ii].y;
rep(i,ll,lr)
if
(prev[i]<d[ii].x) now++;
ans[d[ii].list]=now;
}
}
rep(i,1,T)
printf
(
"%d\n"
,ans[i]);
}
This is still the traditional sub-block Mo team ... The new algorithm put down a story.
MO Team Algorithm Study note "BZOJ2038: small Z socks" "Spoj3267:d-query"