UVALive 5833 Moles(笛卡尔树+搜索+hash)

来源:互联网 发布:mes系统用java开发吗 编辑:程序博客网 时间:2024/06/06 04:57
题目链接
题解:一定是二叉树,建树方法如下:
从第一个数a1开始依次加入,对于第i个ai。首先判断已有的数当中第一个比它大的数x,判断x是否有左二子,没有则加入,如果有那么一定可以加入第一个比ai小的数的右儿子。
建完树以后用dfs先序遍历的方法遍历整个树,求出访问的字符串,然后在hash统计一下就行了。(KMP也行)。注意递归写DFS要爆栈,用非递归来写dfs。
代码如下:(加了读入优化)
#pragma comment(linker, "/STACK:102400000,102400000")#include<iostream>#include<stdio.h>#include<string.h>#include<algorithm>#include<queue>#include<vector>#include<math.h>#include<string>#include<set>#include<map>#define nn 610000using namespace std;typedef long long LL;typedef unsigned long long ULL;int n,a[nn];struct tree{    int val;    int l,r;    void clear()    {        l=r=-1;    }}tr[nn];ULL p[7010];int id[nn];set<int>se;set<int>::iterator it;int num;char s[4*nn];int ls;char s1[7010];int sta[nn];bool L[nn],R[nn];void dfs(int id){    int top,pop;    top=pop=0;    sta[pop++]=id;    for(int i=1;i<=num;i++)        L[i]=R[i]=false;    int tem;    for(;top<pop;)    {        tem=sta[pop-1];        s[ls++]=tr[tem].val+'0';        if(!L[tem])        {            L[tem]=true;            if(tr[tem].l!=-1)            {                sta[pop++]=tr[tem].l;                continue;            }        }        if(!R[tem])        {            R[tem]=true;            if(tr[tem].r!=-1)            {                sta[pop++]=tr[tem].r;                continue;            }        }        pop--;    }}void init(){    p[7000]=1;    for(int i=6999;i>=0;i--)    {        p[i]=p[i+1]*131;    }}int read(){    char ch;    bool flag=false;    int re=0;    while(!(((ch=getchar())>='0'&&(ch<='9'))||(ch=='-')));    if(ch!='-')    {        re*=10;        re+=ch-'0';    }    else        flag=true;    while((ch=getchar())>='0'&&(ch<='9'))    {        re*=10;        re+=ch-'0';    }    if(flag)        re=-re;    return re;}int main(){    int t,i,tcase=0;    scanf("%d",&t);    init();    while(t--)    {        n=read();        for(i=1;i<=n;i++)        {            a[i]=read();        }        scanf("%s",s1);        num=0;        se.clear();        tr[++num].val=a[1]&1;        se.insert(a[1]);        id[a[1]]=num;        tr[num].clear();        for(i=2;i<=n;i++)        {            it=se.upper_bound(a[i]);            if(it==se.end())            {                it--;                tr[id[*it]].r=++num;                tr[num].val=a[i]&1;                id[a[i]]=num;                tr[num].l=tr[num].r=-1;            }            else            {                if(tr[id[*it]].l==-1)                {                    tr[id[*it]].l=++num;                    tr[num].val=a[i]&1;                    tr[num].l=tr[num].r=-1;                    id[a[i]]=num;                }                else                {                    it--;                    tr[id[*it]].r=++num;                    tr[num].val=a[i]&1;                    id[a[i]]=num;                    tr[num].l=tr[num].r=-1;                }            }            se.insert(a[i]);        }        ls=0;        dfs(1);        ULL tmp=0;        ULL tmp1=0;        int len=strlen(s1);        int ans=0;        for(int i=0;i<len;i++)        {            tmp=tmp+s1[i]*p[i];            tmp1=tmp1+s[i]*p[i];        }        if(tmp==tmp1)            ans++;        for(int i=len;i<ls;i++)        {            tmp1=tmp1-s[i-len]*p[0];            tmp1=tmp1*131+s[i]*p[len-1];            if(tmp1==tmp)                ans++;        }        printf("Case #%d: ",++tcase);        printf("%d\n",ans);    }    return 0;}



0 0
原创粉丝点击