https://www.acmicpc.net/problem/2568
2568번: 전깃줄 - 2
첫째 줄에는 두 전봇대 사이의 전깃줄의 개수가 주어진다. 전깃줄의 개수는 100,000 이하의 자연수이다. 둘째 줄부터 한 줄에 하나씩 전깃줄이 A전봇대와 연결되는 위치의 번호와 B전봇대와 연결
www.acmicpc.net
[ 백준 2568번 전깃줄 -2 소스코드 ]
[ 한국정보올림피아드 시도 지역본선 - 지역본선 2007 - 중등부 3번 - 전깃줄 소스코드 ]
#include <stdio.h>
#include <algorithm>
struct wire
{
int a, b;
}aa[1200000];
int sortf(wire x, wire y)
{
if(x.a<y.a) return 1;
else return 0;
}
int a[1200000], b[1200000], c[1200000], d[1200000];
int main()
{
int i;
int l, r, max=0, t, n, x, dab=0, s, k;
scanf("%d", &n);
t=524288;
for(i=t;i<t+n;i++)
scanf("%d %d", &aa[i].a, &aa[i].b);
std::sort(aa+t, aa+t+n, sortf);
for(i=t;i<t+n;i++)
printf("%d %d\n", aa[i].a, aa[i].b);
for(i=t;i<t+n;i++)
{
x=aa[i].b;
l=t;
r=t+x-1;
max=1;
s=-1;
while(1)
{
if(l==r)
{
if(a[l]>=max)
{
max=a[l];
s=b[l];
}
break;
}
if(l&1)
{
if(a[l]>=max)
{
max=a[l];
s=b[l];
}
l++;
}
if(!(r&1))
{
if(a[r]>=max)
{
max=a[r];
s=b[r];
}
r--;
}
if(l>r)
{
if(a[l]>=max)
{
max=a[l];
s=b[l];
}
if(a[r]>=max)
{
max=a[r];
s=b[r];
}
break;
}
l>>=1; // l = l / 2
r>>=1; // r = r / 2
}
l=t+x-1;
c[i]=s;
while(1)
{
if(max+1>=a[l])
{
a[l]=max+1;
b[l]=i;
}
else break;
l>>=1;
if(l==0) break;
}
if(a[t+x-1]>=dab)
{
dab=a[t+x-1];
k=i;
}
}
while(1)
{
if(k<1) break;
d[k]=1;
k=c[k];
}
printf("%d\n", n-dab+1);
for(i=t;i<t+n;i++)
{
if(d[i]==0)
printf("%d\n", aa[i].a);
}
}
'백준 문제풀이' 카테고리의 다른 글
백준 10989 수 정렬하기3 소스 코드 (0) | 2021.10.08 |
---|---|
백준 10814 나이순 정렬 소스 코드 (0) | 2021.10.08 |
백준 2606번 바이러스 - 유니온파인드 (0) | 2021.07.10 |
백준 1181번 단어 정렬 소스 코드 (0) | 2021.07.02 |
백준 2617번 - 구슬찾기 소스 코드 (0) | 2021.06.04 |