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;
}

转载于:https://www.cnblogs.com/dyzll/p/6004373.html

在SystemVerilog中,automatic关键字用于修饰方法内部的变量。如果一个方法被修饰为automatic,那么其内部声明的变量默认都是automatic的。这意味着在进入该方法后,automatic变量会被创建,而离开该方法后就会被销毁。\[1\] 举个例子,如果一个方法内部有一个automatic变量cnt,每次调用该方法时,cnt都会被初始化。因此,每次调用cnt1(1)时,cnt的值都会是1。\[3\] 另一方面,如果一个方法没有被修饰为automatic,那么其中的变量将具有静态的生命周期。这意味着这些变量只会在第一次调用方法时被初始化,之后的调用不会重新初始化这些变量。因此,如果一个方法内部有一个static变量cnt,每次调用cnt2(1)时,cnt的值会累加。第一次调用cnt2(1)时,cnt的值为1,第二次调用cnt2(1)时,cnt的值为2。\[3\] 总结来说,automatic关键字用于修饰方法内部的变量,使其具有自动创建和销毁的特性。而没有被修饰为automatic的变量具有静态的生命周期。 #### 引用[.reference_title] - *1* *3* [staticautomatic 修饰(systemverilog)](https://blog.csdn.net/SummerXRT/article/details/120056366)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [【sv】systemverilog之Automatic](https://blog.csdn.net/weixin_39060517/article/details/122879708)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值