UVALIVE 5792 Trie + 통계
사고: 우 리 는 먼저 두 개의 문자열 을 사전 트 리 에 삽입 하고 접미사 문자열 에 대해 우 리 는 반대로 삽입 한 다음 에 모든 문자 에 대응 하 는 접미사 의 개 수 를 처리 합 니 다.
우 리 는 그룹의 꼬치 를 보 겠 습 니 다. c = a + b.이 c 는 여러 가지 조합 이 있 을 수 있 지만, 우리 가 a 를 가장 많이 취하 면, 이렇게 계산 하 는 것 이 유일한 것 이다.a 가 가장 큰 것 은 a 가 이 접두사 의 마지막 자모 라 는 것 을 찾 으 면 a 가 가장 큰 것 이다.
이것 은 a 가 마지막 자모 인 상황 에 대응 하 는 것 이다. 만약 에 a 뒤에 알파벳 이 있다 면 우 리 는 접미사 가 존재 하 는 지 찾 을 수 있다. 그 는 알파벳 이 하나 밖 에 없다. 그러면 우 리 는 그 를 a 의 뒤에 받 을 수 있다.
그래서 대응 하 는 접두사 a 는 우 리 는 이 두 가지 상황 으로 나 누 어 고려 하면 된다.
롱 롱 사용 에 주의 하 세 요.
#define N 311111
ll ans = 0 ;
ll sum[30] ;
int end[30] ;
struct TT {
    int num ;
    int T[N][26] ;
    TT() {
        num = 0 ;
    }
    void INIT() {
        mem(T[0], -1) ;
        num = 0 ;
    }
    void init(int x) {
        mem(T[x] , -1) ;
    }
    void insert(char *s) {
        int l = strlen(s) ;
        int now = 0 ;
        for (int i = 0 ; i < l ; i ++ ) {
            int a = s[i] - 'a' ;
            if(T[now][a] == -1) {
                T[now][a] = ++ num ;
                init(num) ;
            }
            now = T[now][a] ;
        }
    }
    void cal(int now) {
        for (int i = 0 ; i < 26 ; i ++ ) {
            if(T[now][i] == -1) {
                ans += sum[i] ;
            } else {
                if(end[i])
                    ans ++ ;
                cal(T[now][i]) ;
            }
        }
    }
    int fk(int now) {
        for (int i = 0 ; i < 26 ; i ++ ) {
            if(T[now][i] != -1) {
                sum[i] ++ ;
                fk(T[now][i]) ;
            }
        }
    }
} sufTree , preTree ;
char s[1111] , p[1111] ;
int P , S ;
int main() {
    while(cin >> P >> S, (P + S)) {
        sufTree.INIT() ;
        preTree.INIT() ;
        for (int i = 0 ; i < P ; i ++ ) {
            scanf("%s",p) ;
            preTree.insert(p) ;
        }
        for (int i = 0 ; i < S ; i ++ ) {
            scanf("%s",s) ;int l = strlen(s) ;
            reverse(s , s + l) ;
            sufTree.insert(s) ;
        }
        mem(sum , 0) ;
        mem(end , 0) ;
        ans = 0 ;
        sufTree.fk(0) ;
        for (int i = 0 ; i < 26 ; i ++ )if(sufTree.T[0][i] != -1)end[i] = 1 ;
        for (int i = 0 ; i < 26 ; i ++ )if(preTree.T[0][i] != -1)preTree.cal(preTree.T[0][i]) ;
        printf("%lld
",ans) ;
    }
    return 0 ;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.