bnuoj 34990(后缀数组 或 hash+二分)

后缀数组倍增算法超时,听说用3DC可以勉强过,不愿写了,直接用hash+二分求出log(n)的时间查询两个字符串之间的任意两个位置的最长前缀.

我自己在想hash的时候一直在考虑hash成数值时MOD取多大,如果取10^18的话,那么两数相乘个就超LL了,但是取10^9的话又怕出现重复的可能大.后面才发现自己是sb,如果用unsigned long long 如果有溢出或者为负数是直接变成对(1<<64)取模了。 也就是无符号长整形运算自动帮你取模了。所以可以放心用hash

Justice String

Time Limit: 2000ms

Memory Limit: 65536KB

64-bit integer IO format: %lld      Java class name: Main

Prev

Submit Status Statistics Discuss

Next

Type:

None

None
 
Graph Theory
 
    2-SAT
 
    Articulation/Bridge/Biconnected Component
 
    Cycles/Topological Sorting/Strongly Connected Component
 
    Shortest Path
 
        Bellman Ford
 
        Dijkstra/Floyd Warshall
 
    Euler Trail/Circuit
 
    Heavy-Light Decomposition
 
    Minimum Spanning Tree
 
    Stable Marriage Problem
 
    Trees
 
    Directed Minimum Spanning Tree
 
    Flow/Matching
 
        Graph Matching
 
            Bipartite Matching
 
            Hopcroft–Karp Bipartite Matching
 
            Weighted Bipartite Matching/Hungarian Algorithm
 
        Flow
 
            Max Flow/Min Cut
 
            Min Cost Max Flow
 
DFS-like
 
    Backtracking with Pruning/Branch and Bound
 
    Basic Recursion
 
    IDA* Search
 
    Parsing/Grammar
 
    Breadth First Search/Depth First Search
 
    Advanced Search Techniques
 
        Binary Search/Bisection
 
        Ternary Search
 
Geometry
 
    Basic Geometry
 
    Computational Geometry
 
    Convex Hull
 
    Pick‘s Theorem
 
Game Theory
 
    Green Hackenbush/Colon Principle/Fusion Principle
 
    Nim
 
    Sprague-Grundy Number
 
Matrix
 
    Gaussian Elimination
 
    Matrix Exponentiation
 
Data Structures
 
    Basic Data Structures
 
    Binary Indexed Tree
 
    Binary Search Tree
 
    Hashing
 
    Orthogonal Range Search
 
    Range Minimum Query/Lowest Common Ancestor
 
    Segment Tree/Interval Tree
 
    Trie Tree
 
    Sorting
 
    Disjoint Set
 
String
 
    Aho Corasick
 
    Knuth-Morris-Pratt
 
    Suffix Array/Suffix Tree
 
Math
 
    Basic Math
 
    Big Integer Arithmetic
 
    Number Theory
 
        Chinese Remainder Theorem
 
        Extended Euclid
 
        Inclusion/Exclusion
 
        Modular Arithmetic
 
    Combinatorics
 
        Group Theory/Burnside‘s lemma
 
        Counting
 
    Probability/Expected Value
 
Others
 
    Tricky
 
    Hardest
 
    Unusual
 
    Brute Force
 
    Implementation
 
    Constructive Algorithms
 
    Two Pointer
 
    Bitmask
 
    Beginner
 
    Discrete Logarithm/Shank‘s Baby-step Giant-step Algorithm
 
    Greedy
 
    Divide and Conquer
 
Dynamic Programming
                  Tag it!

Given two strings A and B, your task is to find a substring of A called justice string, which has the same length as B, and only has at most two characters different from B.

Input

The first line of the input contains a single integer T, which is the number of test cases.

For each test case, the first line is string A, and the second is string B.

Both string A and B contain lowercase English letters from a to z only. And the length of these two strings is between 1 and 100000, inclusive.

Output

For each case, first output the case number as "Case #x: ", and x is the case number. Then output a number indicating the start position of substring C in A, position is counted from 0. If there is no such substring C, output -1.

And if there are multiple solutions, output the smallest one.

Sample Input

3
aaabcd
abee
aaaaaa
aaaaa
aaaaaa
aabbb

Sample Output

Case #1: 2
Case #2: 0
Case #3: -1

Source

2014 ACM-ICPC Beijing Invitational Programming Contest

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <string>
#include <algorithm>
#include <math.h>
#include <stdlib.h>
using namespace std;
#define N 100100

#define KEY 31

typedef unsigned long long ul;

char a[N],b[N];
ul base[N];
ul hha[N],hhb[N];
int lena,lenb;

ul gethash(int x,int y,ul g[])
{
    if(x>y)    return 0;
    return g[x]-g[y+1]*base[y+1-x];
}

int lcp(int pa,int pb)//求a串以pa为起始,与b串以pb为起始,最长的前缀
{
    int b=0,d=lenb-pb;//最小一个相同的都没有,最多有lenb个
    while(b<d)
    {
        int mid=(b+d+1)/2;
        if( gethash(pa,pa+mid-1,hha)==gethash(pb,pb+mid-1,hhb) )
            b=mid;
        else d=mid-1;
    }
    return b;
}

int main()
{
    int T;
    int tt=1;
    long long tmp=1;
    for(int i=0;i<N;i++)
    {
        base[i]=tmp;
        tmp*=KEY;
    }

    scanf("%d",&T);
    while(T--)
    {
        scanf("%s%s",a,b);
        lena=strlen(a);
        lenb=strlen(b);
        memset(hha,0,sizeof(hha));
        memset(hhb,0,sizeof(hhb));

        hha[lena]=0;
        for(int i=lena-1;i>=0;i--)
            hha[i] = hha[i+1]*KEY+a[i]-‘a‘;
        hhb[lenb]=0;
        for(int i=lenb-1;i>=0;i--)
            hhb[i] = hhb[i+1]*KEY+b[i]-‘a‘;

        int ans=-1;

        for(int i=0;i<=lena-lenb;i++)
        {
            int cnt=0;
            cnt += lcp(i+cnt,cnt);
            if(cnt>=lenb)
            {
                ans=i;
                break;
            }
            cnt++;
            if(cnt>=lenb)
            {
                ans=i;
                break;
            }
            cnt += lcp(i+cnt,cnt);
            if(cnt>=lenb)
            {
                ans=i;
                break;
            }
            cnt++;
            if(cnt>=lenb)
            {
                ans=i;
                break;
            }
            cnt += lcp(i+cnt,cnt);
            if(cnt>=lenb)
            {
                ans=i;
                break;
            }
        }
        printf("Case #%d: ",tt++);
        printf("%d\n",ans);
        //printf("%d %s\n",ans,a+ans);
    }
    return 0;
}
时间: 2024-11-05 22:56:58

bnuoj 34990(后缀数组 或 hash+二分)的相关文章

poj 3882(Stammering Aliens) 后缀数组 或者 hash

后缀数组:  构建后缀数组,注意要在字符串莫末尾加上一个没出现过的字符.然后可以2分或者直接扫描,直接扫描需要用单调队列来维护 VIEW CODE #include<cstdio> #include<algorithm> #include<iostream> #include<cmath> #include<queue> #include<stack> #include<string> #include<cstrin

UVALive - 8086 Substring Sorting (后缀数组+线段树上二分)

题意: 给一个串S, 多次询问k和m,求S的所有长度为k的不同子串中,字典序为排第m的串的最早出现位置 简化问题: 如果没有长度k的限制,并且没有不同子串的限制要怎么做.要字典序第m大,容易想到用后缀数组,因为它就是将n个后缀按字典序排好的,设f(i) = 排名<=i的所有后缀的所有前缀的个数和,假设答案的串是排名i的后缀的前缀,那么有f(i) >= k 且 f(i-1) < k,则满足二分性,可以二分后缀排名解决. 扩展: 有不同子串的限制,则类似求一个串有多少不同子串那样,对于每个排

【后缀数组】【二分答案】【差分】poj1743 Musical Theme

差分消除加减一个值得影响,貌似r二分上界要设成(n-2)/2?为啥? sa求不可重叠最长重复子串 给定一个字符串,求最长重复子串,这两个子串不能重叠.算法分析:这题比上一题稍复杂一点.先二分答案,把题目变成判定性问题:判断是否存在两个长度为 k 的子串是相同的,且不重叠.解决这个问题的关键还是利用height 数组.把排序后的后缀分成若干组,其中每组的后缀之间的 height 值都不小于 k. 容易看出,有希望成为最长公共前缀不小于 k 的两个后缀一定在同一组. 然后对于每组后缀,只须判断每个后

【后缀数组】【二分答案】poj3261

注意:对整型数组求sa时,s[n]请置成-1. 请离散化. 可重叠的 k 次最长重复子串(pku3261)给定一个字符串,求至少出现 k 次的最长重复子串,这 k 个子串可以重叠.算法分析:先二分答案,然后将后缀分成若干组. 不同的是,这里要判断的是有没有一个组的后缀个数不小于 k.如果有,那么存在k 个相同的子串满足条件,否则不存在.这个做法的时间复杂度为 O(nlogn). #include<cstdio> #include<algorithm> #include<cst

BNU 34990 Justice String (hash+二分求LCP)

思路:枚举第一个字符串的位置,然后枚举最长公共前缀的长度,时间即会下降-- #pragma comment(linker, "/STACK:1024000000,1024000000") #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<map> #include<queue> #include<

【POJ1743】Musical Themes 乐曲主题 后缀数组、 (也可以用hash+二分做的~)

题意: 1829: Musical Themes 乐曲主题 Time Limit: 1 Sec  Memory Limit: 128 MB Submit: 42  Solved: 15 [Submit][Status][Web Board] Description 我们用N(1 <= N <=5000)个音符的序列来表示一首乐曲,每个音符都是1..88范围内的整数,每个数表示钢琴上的一个键.很不幸这种表示旋律的方法忽略了音符的时值,但这项编程任务是关于音高的,与时值无关. 许多作曲家围绕一个重

POJ3261---Milk Patterns(后缀数组+二分)

Description Farmer John has noticed that the quality of milk given by his cows varies from day to day. On further investigation, he discovered that although he can't predict the quality of milk from one day to the next, there are some regular pattern

POJ1226---Substrings(后缀数组+二分)

Description You are given a number of case-sensitive strings of alphabetic characters, find the largest string X, such that either X, or its inverse can be found as a substring of any of the given strings. Input The first line of the input contains a

SPOJ220---Relevant Phrases of Annihilation(后缀数组+二分,对后缀分组)

You are the King of Byteland. Your agents have just intercepted a batch of encrypted enemy messages concerning the date of the planned attack on your island. You immedietaly send for the Bytelandian Cryptographer, but he is currently busy eating popc