문자열 - 아호 코라식(Aho-Corasick)
아호 코라식(Aho-Corasick)에 대해 알아보자.
벌써 코포를 시작한지 한달 정도가 넘어간다.
div2만 들어서면 2솔밖에 못한다..
3솔의 벽이 너무 높다. 아이디어도 못떠올리는 경우가 대다수이다.
“dp 같긴한데…, greedy같긴한데..”생각만하고 못풀 때도 많다.
문제점 잡기가 어렵다. 3솔의 벽을 깨보기 위해 이번에는 C, D만 업솔빙 해보려고 한다.
문제를 조금 읽고 보면 dp같긴했다. 평소 2차원 dp의 좀 복잡한 형태는 항상 못풀었었고 자신감이 없었따…
dp가 맞긴맞았는데 잘못 짚었다. 4칸을 기준으로 보면 상황은 다음 그림과 같다.
보면 2, 0, -2밖에 되지 않는다. 따라서 경로를 적절히 조절하여 2씩 줄이거나 늘릴 수 있다는 뜻이다.
즉 끝점에서의 min, max값이 min <= 0 <= max 이고 2, 0, -2 단위면 적절히 조절하여 0을 만들 수 있다는 뜻이다.
mindp[0][0] = maxdp[0][0] = grid[0][0];
for(int i=1;i<n;i++){
mindp[i][0] = maxdp[i][0] = mindp[i-1][0]+grid[i][0];
}
for(int j=1;j<m;j++){
mindp[0][j] = maxdp[0][j] = mindp[0][j-1] +grid[0][j];
}
for(int i=1;i<n;i++){
for(int j=1;j<m;j++){
mindp[i][j] = min(mindp[i-1][j], mindp[i][j-1]) + grid[i][j];
maxdp[i][j] = max(maxdp[i-1][j], maxdp[i][j-1]) + grid[i][j];
}
}
if((maxdp[n-1][m-1]%2)||mindp[n-1][m-1]>0||maxdp[n-1][m-1]<0) cout << "NO\n";
else cout << "YES\n";
C가 자신이 없었기에 contest당시에는 D를 더 오래봤다.
근데 끝나고 디코반응같은걸 보니 D가 은근히 복병이었던것 같다.
그래프를 만들고 트리의 지름 문제 처럼 접근하려고 했다. DFS해서 가장 멀리 있는 것을 찾고, 그 다음 남은 서브트리를 찾고,..그런식으로..
예제 3번조차 잘 안됐다. 아이디어가 틀렸던 것 같다.
업솔빙도 오래걸렸다. 위의 문장을 쓰고 2시간이 지났다 ㅋㅋㅋㅋ
내가 영어를 못하는건지 문제가 눈에 하나도 안들어왔는데 이제야 좀 알겠다.
차수가 1이면 1개로 그냥 판단된다. 차수가 2여도 한방에 그냥 판단된다.
그니까 차수가 3개이상일 때만 판단하려면 2번이상 봐야한다. 근데 이걸 볼때도 루트기준으로 (서브트리에서 온 거) + (일자인거 갯수-1)을 해줘야한다.
그냥 무작정 차수가 3개이상이면 degree-1 하고 더하면 문제가 된다.
왜냐하면 서브트리를 판단할 때 썼던 간선이 다른걸 판단 할 때 또 쓰여서 중복으로 세질 수 있기 때문이다.
그래서 각 루트를 기준으로 세서 최소값을 출력한다.
int dfs(int i, int p) {
int sm = 0, z = 0; //sm은 서브트리에서 온 k개수, z는 서브트리 중 일자인거 개수이다
for (int j : tree[i]) if (j != p) { //부모노드 빼고 검사하고
int x = dfs(j, i);
sm += x;
if (x == 0) //일자면
z++;
}
return sm + max(0, z - 1); //부모노드 제외하고 2개이상이어야 카운트 된다.
}
특징은 간선이 3개 이상인 곳에서 검사하면 모든 정점 검사할 필요없이 끝이긴하다.(왜그런진 모름..)
이런 문제 옛날에 어디선가 풀었던 것같은데 라는 생각만 계속하다가 결국 아무것도 못했다.
난 이런 문제가 젤 어렵다 손으로 하면 되긴하는데 컴퓨터로 어케하지 싶은 문제들..
그래서 맨날 C번을 못푸나 보다 ㅠㅠ
중요한건 인접한 것의 크기비교였다. 만약에 a[i] < a[i+1]이면 오른쪽 시작(suffix)으로 빼야한다. 왜냐면 왼쪽시작(prefix)으로 빼면 이미 작은데 더 빼서 손해기 때문이다.
빼는 양의 정도는 a[i+1]-a[i]일 것이다. 크기를 똑같이 만들어 같이 움직여야한다. 그러면서 평평하게 만들어지고, 그렇다면 그 평평할 때 의 높이 curh를 저장해놓고 마지막에 더해주면 된다.
이래도 되는 이유는 인접한거는 세트로 움직이기 때문이다 그러니까 차이가 변하질 않는다.
a배열의 값이 10억이므로 답은 int형을 훌쩍 넘어갈 수 있다. 따라서 long long으로 해줘야한다.
long long res = 0;
long long curh = a[0];
for(int i = 0; i < n-1; i++) {
res += abs(a[i] - a[i+1]);
if(a[i] > a[i+1]) {
curh += a[i+1] - a[i]; //깎일 수도있고 늘어날수도 있으니 이건 절댓값 안붙여
}
}
cout << res+abs(curh)<<'\n';
C에 올인해서 문제도 안읽어 봤다.
읽어보니 일단 왼쪽에서 넣는게 이득이라는 것을 확인됐다.
조금 이해가 안되는건 높은곳에서 낮은쪽으로 가는게 아니라 그냥 왼쪽이 꽉차면 오른쪽으로 간다.
그림을 위와 같이 그려놔서 내가 해석을 제대로 한건가? 헷갈렸다. ㅋㅋㅋ
cin >> n;
vol = vector<ll> (n+1);
mintime = vector<ll> (n+1);
ll sum = 0;
for(int i=1;i<=n;i++){
cin >> vol[i];
}
mintime[0] =0;
for(int i=1;i<=n;i++){
sum += vol[i];
// i개 썼을 떄 i개 다 채울라면 몇초 걸림?
// 앞에께 크면 앞에꺼 만큼 걸리고, 뒤에께 크면 앞에서 좀 흘러나온거 받음
// 나눗셈연산 생각해서 올림처리 해줌
mintime[i] = max(mintime[i-1], (sum+i-1)/i);
}
cin >> q;
while (q--){
ll query;
cin >> query;
ll rst = (sum+query-1)/query;
if(rst<=n&&mintime[rst]<=query) cout << rst << '\n';
else cout << -1 << '\n';
}
아호 코라식(Aho-Corasick)에 대해 알아보자.
docker를 이해해보자
2060 염소줄서기 풀이 및 코드
분할정복을 이용한 다이나믹 프로그래밍 최적화
코드포스 다시 열심히! 블로그도 열심히!
rust 공부시작!
코드포스 블루 달성 후기
여름캠프 및 SUAPC 후기
2023-05-25-Edu Codeforce round 149 (Div.2)
2023-05-13-Edu Codeforce round 148 (Div.2)
HLD(Heavy Light Decomposition)
행렬 거듭 제곱
2023-05-02-It takes two
Codeforce round 868 (Div.2)
2월 11일 문제풀이
Codeforces#846, TypeDB Foreces 2023, Codeforces#848 업솔빙
ps5 게임 : 용과같이 제로 리뷰
백준 23877번 Convoluted Intervals 문제풀이
codeforce round #828(div 3), EDU #137(div 2) 업솔빙
codeforce round #823(div 2), #824(div 2) 업솔빙
AtCoder Beginner Contest 270 업솔빙
ps5 게임 : 용과같이 극 1 리뷰
백준 18719번 Binomal 문제풀이
백준 14288번 회사문화4 문제풀이
백준 3308번 Matching 문제풀이
백준 18186번 라면사기(large) 문제풀이
백준 4196번 도미노 문제풀이
백준 3176번 도로 네트워크 문제풀이
백준 16367번 TV Show Game 문제풀이
ps5 게임 : 페르소나 5 더 로열 리뷰
codeforce round #811(div 3), #812(div 2), CodeTon round 2 업솔빙
백준 21162번 뒤집기 K 문제풀이
codeforce round #808(div 2), #803(div 2, virtual) 업솔빙
codeforce round #807(div 2) 업솔빙
백준 10167번 금광 문제풀이
codeforce round #805(div 3), #806(div 4) 업솔빙
백준 18253번 최단경로와 쿼리 문제풀이
에듀 라운드 131 업솔빙
백준 1949번 우수 마을 문제풀이
백준 3665번 최종 순위 문제풀이
Trie 자료구조 이해하기
merge sort를 이용하여 inversion 개수세기
3솔의 벽이 너무 높다..
lazy propagation없이 구간 갱신하기
코드포스 폭망기념 upsolving
백준 11505 구간 곱 구하기 문제풀이
백준 1305 광고 문제풀이
백준 4386 별자리 만들기 문제풀이
백준 4803 트리
백준 2206 벽 부수고 이동하기 문제풀이
백준 2166 다각형의 면적 문제풀이
백준 12015 가장 긴 증가하는 부분 수열2 문제풀이
백준 10986 나머지합 문제풀이
스택 구현하기 ========== 자료구조의 기본이라고 하면 스택 과 큐가 있다 백준 10828번에서 마주친 스택
매우매우 많은 정렬이 있지만 그중 가장 안 어려운 3가지를 공부해보았다.
Leave a comment