-
Notifications
You must be signed in to change notification settings - Fork 59
/
Copy pathPROKLETNIK.cpp
103 lines (85 loc) · 3.02 KB
/
PROKLETNIK.cpp
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
# include <bits/stdc++.h>
# define NR 250000
using namespace std;
//ifstream f("test.in");
//ofstream g("test.out");
struct elem {
int nr, poz;
}RMQmax[20][NR], RMQminST[20][NR], RMQminDR[20][NR];
int i,j,n,m,Lmax,ci,cs,nrQ;
int lg[NR], a[NR];
void logaritmi() {
for (int i=2; i<=n; ++i)
lg[i]=lg[i/2]+1;
}
int pozMax (int ci, int cs) {
int log=lg[cs-ci+1];
if (RMQmax[log][ci].nr >= RMQmax[log][cs-(1<<log)+1].nr) return RMQmax[log][ci].poz;
else return RMQmax[log][cs-(1<<log)+1].poz;
}
int pozMinST (int ci, int cs) {
int log=lg[cs-ci+1];
if (RMQminST[log][ci].nr <= RMQminST[log][cs-(1<<log)+1].nr) return RMQminST[log][ci].poz;
else return RMQminST[log][cs-(1<<log)+1].poz;
}
int pozMinDR (int ci, int cs) {
int log=lg[cs-ci+1];
if (RMQminDR[log][ci].nr < RMQminDR[log][cs-(1<<log)+1].nr) return RMQminDR[log][ci].poz;
else return RMQminDR[log][cs-(1<<log)+1].poz;
}
void query (int ci, int cs) {
if (cs-ci+1<=Lmax) return;
int paux, sol, pant, ciVAR, csVAR, pozMAX, ant;
vector <int> v;
v.push_back(ci); pant=ci; ant=0;
while (1 && pant<=cs) {
pozMAX=pozMax(pant, cs);
if (a[pozMAX] < ant) break;
else { // e tot maxim
v.push_back(pozMAX);
pant=pozMAX+1; ant=a[pozMAX];
}
}
v.push_back(cs);
for (int i=0; i<v.size()-2; ++i) {
//fac cautare binara in stanga
ciVAR=v[i]; pozMAX=v[i+1]; csVAR=v[i+2];
sol=pozMinST(ci, pozMAX);
Lmax=max(Lmax, pozMAX - sol+1);
//fac cautare binara in dreapta
sol=pozMinDR(pozMAX, cs);
Lmax=max(Lmax, sol - pozMAX+1);
if (ciVAR < pozMAX) query (ciVAR, pozMAX-1);
if (pozMAX < csVAR) query (pozMAX+1, csVAR);
}
v.clear();
}
int main ()
{
cin>>n; logaritmi ();
for (i=1; i<=n; ++i) {
cin>>a[i];
RMQminST[0][i].nr=a[i];
RMQminST[0][i].poz=i;
RMQminDR[0][i].nr=a[i];
RMQminDR[0][i].poz=i;
RMQmax[0][i].nr=a[i];
RMQmax[0][i].poz=i;
}
for (i=1; i<=lg[n]; ++i)
for (j=1; j<=n-(1<<i)+1; ++j) {
if (RMQminST[i-1][j].nr <= RMQminST[i-1][j+(1<<(i-1))].nr) RMQminST[i][j]=RMQminST[i-1][j];
else RMQminST[i][j]=RMQminST[i-1][j+(1<<(i-1))];
if (RMQminDR[i-1][j].nr < RMQminDR[i-1][j+(1<<(i-1))].nr) RMQminDR[i][j]=RMQminDR[i-1][j];
else RMQminDR[i][j]=RMQminDR[i-1][j+(1<<(i-1))];
if (RMQmax[i-1][j].nr >= RMQmax[i-1][j+(1<<(i-1))].nr) RMQmax[i][j]=RMQmax[i-1][j];
else RMQmax[i][j]=RMQmax[i-1][j+(1<<(i-1))];
}
cin>>nrQ;
for (i=1; i<=nrQ; ++i) {
cin>>ci>>cs; Lmax=1;
query (ci, cs);
cout<<Lmax<<"\n";
}
return 0;
}