Automatic Trading

Automatic Trading

A brokerage firm is interested in detecting automatic trading. They believe that a particular algorithm repeats itself; that is, it makes the same sequence of trades at a later time. The firm has identified a set of 26 key stocks that they believe are likely to be traded in concert, and they’ve encoded a series of trades as a string of letters: the letter itself indicates the stock, upper case indicates a buy, lower case indicates a sell. They want you to write a program to determine, for any two starting points, the longest sequence of identical trades from those two starting points, starting from and including those starting points as the first trade in the sequence.

Input

There will be a single test case in the input. This test case will start with a string ss on the first line, consisting solely of upper case and lower case letters (1length(s)1000001≤length(s)≤100000). On the next line will be an integer qq (1q1000001≤q≤100000), indicating the number of queries. The following qq lines each describe a query with two integers, ii and jj (0i<j<length(s)0≤i<j<length(s)), which represent two zero-based positions in the string.

Output

For each query, output a single integer, indicating the length of the longest sequence of trades starting at iiwhich is identical to the sequence of trades starting at jj.

Sample Input 1Sample Output 1
ABABABcABABAbAbab
3
0 2
1 6
0 7
4
0
5
Sample Input 2Sample Output 2
SheSellsSeashellsByTheSeaShore
4
8 22
1 20
8 25
0 1
3
4
1
0

分析:后缀数组+RMQ;(二分哈希)

   i和j的最长公共前缀是i和j的后缀在字典序中的夹的height值的最小的一个;

代码:

后缀数组:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <climits>
#include <cstring>
#include <string>
#include <set>
#include <map>
#include <unordered_map>
#include <queue>
#include <stack>
#include <vector>
#include <list>
#define rep(i,m,n) for(i=m;i<=n;i++)
#define rsp(it,s) for(set<int>::iterator it=s.begin();it!=s.end();it++)
#define mod 1000000007
#define inf 0x3f3f3f3f
#define vi vector<int>
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define ll long long
#define pi acos(-1.0)
#define pii pair<int,int>
#define Lson L, mid, ls[rt]
#define Rson mid+1, R, rs[rt]
#define sys system("pause")
#define freopen freopen("in.txt","r",stdin)
const int maxn=1e5+10;
using namespace std;
ll gcd(ll p,ll q){return q==0?p:gcd(q,p%q);}
ll qpow(ll p,ll q){ll f=1;while(q){if(q&1)f=f*p;p=p*p;q>>=1;}return f;}
inline ll read()
{
    ll x=0;int f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
int n,m,k,t,cntA[maxn],cntB[maxn],sa[maxn],lev[maxn],height[maxn],A[maxn],B[maxn],tsa[maxn],p[maxn],st[20][maxn];
char ch[maxn];
void init()
{
    for(int i=2;i<=n+1;i++)p[i]=1+p[i>>1];
    for(int i=1;i<=n+1;i++)st[0][i]=height[i];
    for(int i=1;i<=19;i++)
        for(int j=1;(ll)j+(1LL<<i)-1<=n+1;j++)
            st[i][j]=min(st[i-1][j],st[i-1][j+(1<<(i-1))]);
}
int query(int a,int b)
{
    if(a>b)swap(a,b);
    a++;
    int x=p[b-a+1];
    return min(st[x][a],st[x][b-(1<<x)+1]);
}
void solve()
{
    for (int i = 0; i < 256; i ++) cntA[i] = 0;
    for (int i = 1; i <= n; i ++) cntA[ch[i]] ++;
    for (int i = 1; i < 256; i ++) cntA[i] += cntA[i - 1];
    for (int i = n; i; i --) sa[cntA[ch[i]] --] = i;
    lev[sa[1]] = 1;
    for (int i = 2; i <= n; i ++)
    {
        lev[sa[i]] = lev[sa[i - 1]];
        if (ch[sa[i]] != ch[sa[i - 1]]) lev[sa[i]] ++;
    }
    for (int l = 1; lev[sa[n]] < n; l <<= 1)
    {
        for (int i = 0; i <= n; i ++) cntA[i] = 0;
        for (int i = 0; i <= n; i ++) cntB[i] = 0;
        for (int i = 1; i <= n; i ++)
        {
            cntA[A[i] = lev[i]] ++;
            cntB[B[i] = (i + l <= n) ? lev[i + l] : 0] ++;
        }
        for (int i = 1; i <= n; i ++) cntB[i] += cntB[i - 1];
        for (int i = n; i; i --) tsa[cntB[B[i]] --] = i;
        for (int i = 1; i <= n; i ++) cntA[i] += cntA[i - 1];
        for (int i = n; i; i --) sa[cntA[A[tsa[i]]] --] = tsa[i];
        lev[sa[1]] = 1;
        for (int i = 2; i <= n; i ++)
        {
            lev[sa[i]] = lev[sa[i - 1]];
            if (A[sa[i]] != A[sa[i - 1]] || B[sa[i]] != B[sa[i - 1]]) lev[sa[i]] ++;
        }
    }
    for (int i = 1, j = 0; i <= n; i ++)
    {
        if (j) j --;
        while (ch[i + j] == ch[sa[lev[i] - 1] + j]) j ++;
        height[lev[i]] = j;
    }
}
int main()
{
    int i,j;
    while(~scanf("%s",ch+1)&&strcmp(ch+1,"*")!=0)
    {
        n=strlen(ch+1);
        solve();
        init();
        scanf("%d",&m);
        while(m--)
        {
            int a,b;
            scanf("%d%d",&a,&b);
            a++,b++;
            printf("%d\n",query(lev[a],lev[b]));
        }
    }
    //system("Pause");
    return 0;
}

二分哈希:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <climits>
#include <cstring>
#include <string>
#include <set>
#include <map>
#include <unordered_map>
#include <queue>
#include <stack>
#include <vector>
#include <list>
#define rep(i,m,n) for(i=m;i<=n;i++)
#define rsp(it,s) for(set<int>::iterator it=s.begin();it!=s.end();it++)
#define mod 1000000007
#define inf 0x3f3f3f3f
#define vi vector<int>
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define ll long long
#define pi acos(-1.0)
#define pii pair<int,int>
#define Lson L, mid, ls[rt]
#define Rson mid+1, R, rs[rt]
#define sys system("pause")
#define freopen freopen("in.txt","r",stdin)
const int maxn=1e5+10;
const int mo=123;
using namespace std;
ll gcd(ll p,ll q){return q==0?p:gcd(q,p%q);}
ll qpow(ll p,ll q){ll f=1;while(q){if(q&1)f=f*p;p=p*p;q>>=1;}return f;}
inline ll read()
{
    ll x=0;int f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
int n,m,k,t,len;
unsigned ll h[maxn],xp[maxn];
char a[maxn];
void init()
{
    xp[0]=1;
    for(int i=1;i<=maxn-5;i++)xp[i]=xp[i-1]*mo;
}
bool check(int p,int b,int c)
{
    return h[b]-h[b+p]*xp[p]==h[c]-h[c+p]*xp[p];
}
int main()
{
    int i,j;
    init();
    while(~scanf("%s",a)&&strcmp(a,"*")!=0)
    {
        len=strlen(a);
        h[len]=0;
        for(i=len-1;i>=0;i--)
        {
            h[i]=h[i+1]*mo+(a[i]>='a'?a[i]-'a':a[i]-'A'+26);
        }
        scanf("%d",&n);
        while(n--)
        {
            int b,c;
            scanf("%d%d",&b,&c);
            int l=0,r=len-max(b,c),ans;
            while(l<=r)
            {
                int mid=l+r>>1;
                if(check(mid,b,c))ans=mid,l=mid+1;
                else r=mid-1;
            }
            printf("%d\n",ans);
        }
    }
    //system("Pause");
    return 0;
}
posted @ 2016-10-27 16:12  mxzf0213  阅读(252)  评论(0编辑  收藏  举报