forked from Sandip-Jana/Algorithms-ACM-ICPC
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathSegmentTreeSquareRootDecomposition.txt
More file actions
112 lines (111 loc) · 3.33 KB
/
SegmentTreeSquareRootDecomposition.txt
File metadata and controls
112 lines (111 loc) · 3.33 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
//package segmenttreelazyprop;
import java.io.*;
import java.util.*;
class SegmentTreeSquareRootDecomp
{
static int a[]=new int[100010];
static int stree[];
static int cnt[]=new int[100010];
public static void main(String args[])throws IOException
{
BufferedReader in=new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st=new StringTokenizer(in.readLine());
int n=Integer.parseInt(st.nextToken());
int m=Integer.parseInt(st.nextToken());
st=new StringTokenizer(in.readLine());
// int a[]=new int[n];
for(int i=1;i<=n;i++)
a[i]=Integer.parseInt(st.nextToken());
int len=2*(int)(Math.pow(2,(Math.log(n)/Math.log(2))+1));
stree=new int[len];
build_tree(1,1,n);
Node node[]=new Node[m];
for(int i=0;i<m;i++)
{
st=new StringTokenizer(in.readLine());
node[i]=new Node();
node[i].L=Integer.parseInt(st.nextToken());
node[i].R=Integer.parseInt(st.nextToken());
node[i].i=i;
}
Arrays.sort(node , new Comparator<Node>(){
@Override
public int compare(Node x,Node y)
{
if(x.L/555!=y.L/555)
return x.L/555-y.L/555;
else
return x.R-y.R;
}
});
int currentL=1;
int currentR=1;
int max=0;
int ans[]=new int[m];
for(int i=0;i<m;i++)
{
int L=node[i].L;
int R=node[i].R;
max=query_tree(1,1,n,L,R);
while(currentL<L)
{
remove(currentL);
currentL++;
}
while(currentR<=R)
{
add(currentR);
currentR++;
}
while(currentL>L)
{
add(currentL-1);
currentL--;
}
while(currentR>R+1)
{
remove(currentR-1);
currentR--;
}
ans[node[i].i]=cnt[max];
}
for(int i=0;i<m;i++)
System.out.println(ans[i]);
}
public static void add(int index)
{
cnt[a[index]]+=1;
}
public static void remove(int index)
{
cnt[a[index]]-=1;
}
public static void build_tree(int index,int l,int r)
{
if(l==r)
{
stree[index]=a[l];
return;
}
if(l>r)
return;
int mid=(l+r)/2;
build_tree(2*index,l,mid);
build_tree(2*index+1,mid+1,r);
stree[index]=Math.max(stree[2*index],stree[2*index+1]);
}
public static int query_tree(int index,int l,int r,int i,int j)
{
if(i>r || j<l) return -1;
if(i<=l && j>=r)
return stree[index];
int mid=(l+r)/2;
int left=query_tree(2*index,l,mid,i,j);
int right=query_tree(2*index+1,mid+1,r,i,j);
return Math.max(left,right);
}
}
class Node
{
int i,L,R;
}