您的位置:首页 > 其它

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

2014-10-27 20:13 489 查看
题目链接

题解:一定是二叉树,建树方法如下:
从第一个数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 610000
using 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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: