# | 제출 시각 | 아이디 | 문제 | 언어 | 결과 | 실행 시간 | 메모리 |
---|---|---|---|---|---|---|---|
813423 | ZHIRDILBILDIZ | Financial Report (JOI21_financial) | C++14 | 0 ms | 0 KiB |
이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#include<bits/stdc++.h>
#define fi first
#define se second
#define ll long long
using namespace std ;
const int N = (1 << 19) ;
int n, d, cnt, ans, dp[N + 1], p[N + 1], kol[N + 1], mn[N + 1], mx[N + 1] ;
pair<int, int> a[N + 1] ;
int get(int a)
{
while(a != p[a])
a = p[a] ;
return a ;
}
void join(int a, int b)
{
a = get(a) ;
b = get(b) ;
if(a == b)
return ;
if(kol[a] > kol[b])
swap(a, b) ;
mn[b] = min(mn[a], mn[b]) ;
kol[b] += kol[a] ;
kol[a] = 0 ;
p[a] = b ;
}
int get_min(int a)
{
a = get(a) ;
return mn[a] ;
}
void update(int l, int r, int ind, int num, int v)
{
if(l > ind || r < ind)
return ;
if(l == r)
{
mx[v] = num ;
return ;
}
int mid = (l + r) >> 1 ;
update(l, mid, ind, num, v * 2) ;
update(mid + 1, r, ind, num, v * 2 + 1) ;
mx[v] = max(mx[v * 2], mx[v * 2 + 1]) ;
}
int get_max(int l, int r, int l1, int r1, int v)
{
if(l > r1 || r < l1)
return 0 ;
if(l1 <= l && r <= r1)
return mx[v] ;
int mid = (l + r) >> 1 ;
return max(get_max(l, mid, l1, r1, v * 2), get_max(mid + 1, r, l1, r1, v * 2 + 1)) ;
}
bool cmp(pair<int, int> p1, pair<int, int> p2)
{
if(p1.fi != p2.fi)
return p1.fi < p2.fi ;
else
return p1.se > p2.se ;
}
signed main()
{
ios_base::sync_with_stdio( 0 ) ;
cin.tie( 0 ) ;
cout.tie( 0 ) ;
cin >> n >> d ;
for(int i = 1 ; i <= n ; i++)
{
cin >> a[i].fi ;
p[i] = i ;
mn[i] = i ;
kol[i] = 1 ;
a[i].se = i ;
}
sort(a + 1, a + n + 1, cmp) ;
for(int i = 1 ; i <= n ; i++)
{
cnt++ ;
a[i].fi = cnt ;
}
for(int i = 1 ; i <= n ; i++)
{
int l1 = 0, r1 = a[i].se + 1, l2 = a[i].se - 1, r2 = n + 1, num = 1 ;
dp[a[i].se] = 1 ;
while(l1 + 1 < r1)
{
int mid = (l1 + r1) >> 1 ;
if(get_max(1, N, mid, a[i].se, 1))
l1 = mid ;
else
r1 = mid ;
}
while(l2 + 1 < r2)
{
int mid = (l2 + r2) >> 1 ;
if(get_max(1, N, a[i].se, mid, 1))
r2 = mid ;
else
l2 = mid ;
}
if(r2 - a[i].se >= d)
{
num = get_max(1, N, a[i].se, r2, 1) ;
if(num)
join(a[i].se, r2) ;
}
if(a[i].se - l1 >= d)
{
num = get_max(1, N, l1, a[i].se, 1) ;
if(num)
join(a[i].se, l1) ;
dp[a[i].se] = num + 1 ;
update(1, N, a[i.se], num + 1, 1) ;
}
ans = max(ans, dp[a[i].se]) ;
}
cout << ans ;
return 0 ;
}
//8 8
//4 5 1 3 6 2 7 10