문제: icpc.me/11046
길이가 최대 100만인 문자열 s가 주어질 때 s의 인덱스 l~r 까지의 부분 문자열이 팰린드롬인지 쿼리마다 출력하는 문제이다.
n이 작다면 n^2의 방법으로 해결해줄 수 있지만 n이 크므로 manacher's 알고리즘을 이용하여 해결해주어야 한다.
manacher's 알고리즘으로 전처리를 해준 뒤 중심으로 부터의 최대 팰린드롬 길이와 주어진 구간의 길이를 비교해주어 답을 출력해주면 된다.
시간 복잡도는 O(N+M)이다.
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 | #include <cstdio> #include <algorithm> #include <string> #include <iostream> #include <cstring> #include <vector> using namespace std; int n,m,l,r; vector<int> x,y; vector<int> manacher(vector<int> &s,int n){ vector<int> a(n+1,0); int r=0,p=0; for(int i=1;i<=n;i++){ if(i<=r)a[i]=min(a[2*p-i],r-i); while(0<i-a[i]-1&&i+a[i]+1<=n&&s[i-a[i]-1]==s[i+a[i]+1])a[i]++; if(r<i+a[i]){ r=i+a[i]; p=i; } } return a; } int main(){ scanf("%d",&n); x.assign(n+1,0); y.assign(2*n+2,0); for(int i=1;i<=n;i++){ scanf("%d",&x[i]); y[i*2]=x[i]; } vector<int> a=manacher(x,n); vector<int> b=manacher(y,2*n+1); scanf("%d",&m); while(m--){ scanf("%d%d",&l,&r); if((r-l)%2){ int mid=(r-l+2); printf("%d\n",b[mid]/2>=(r-l)/2+1?1:0); } else{ int mid=(l+r)/2; printf("%d\n",a[mid]>=(r-l)/2?1:0); } } return 0; } | cs |
'알고리즘 관련 > BOJ' 카테고리의 다른 글
BOJ)14965 Lozinke (0) | 2018.06.26 |
---|---|
BOJ)11964 Fruit Feast (0) | 2018.06.25 |
BOJ)1222 홍준 프로그래밍 대회 (0) | 2018.06.25 |
BOJ)15675 괴도 강산 (0) | 2018.06.24 |
BOJ)13016 내 왼손에는 흑염룡이 잠들어 있다 (0) | 2018.06.24 |