(AC仅限于hdu,跑了3900+ms,险过。不过在poj上TLE,因为poj上的时间是3000ms)
解题思路:
对于此题首先将所给的数字构造一棵平衡二叉树,不过不能用纯模拟去构造这棵树,
因为所给的数字构成的树可能就是一条链状!若用纯模拟去构造的话无疑会TLE!
那么我们观察易得下一个数字的父节点必定是当前已加入的所有节点中比下一个节点大
的所有数中的一个最小值,或者是当前已加入的所有节点中比下一个节点小的所有数中的最大值。
有了这个结论后,我们就可以用线段树去维护并查找当前满足要求的最大值或最小值。
#include <iostream>
#include <cstring>
#include <algorithm>
#include <string>
#include <set>
#include <cstdio>
#define N 601000
#include <stack>
using namespace std;
int num[N];
int node[N][3];
int n;
char str[N*20];
int cnt;
stack<int>myst;
char s[N*20];
int in()
{
char ch;
int a = 0;
while((ch = getchar()) == ' ' || ch == '\n');
a += ch - '0';
while((ch = getchar()) != ' ' && ch != '\n')
{
a *= 10;
a += ch - '0';
}
return a;
}
void dfs(int val)
{
cnt=0;
while(!myst.empty())
myst.pop();
myst.push(val);
while(!myst.empty())
{
int fa=myst.top();
str[cnt++]=(fa&1)?'1':'0';
if(node[fa][0])myst.push(node[fa][0]),node[fa][0]=0;
else if(node[fa][1])
myst.push(node[fa][1]),node[fa][1]=0;
else myst.pop();
}
str[cnt]='\0';
}
//*************************************KMP
int next[N*2];
int len;
void get_next()
{
len=strlen(s);
next[0]=-1;
int i,j=-1;
for(i=1; i<len; i++)
{
while(j!=-1&&s[j+1]!=s[i])
j=next[j];
if(s[j+1]==s[i]) j++;
next[i]=j;
}
}
void KMP(int tot)
{
get_next();
int i,j=-1,ans=0;
for(i=0; i<cnt; i++)
{
while(j!=-1&&s[j+1]!=str[i])
j=next[j];
if(s[j+1]==str[i]) j++;
if(j==len-1)
{
ans++;
j=next[j];
}
}
printf("Case #%d: %d\n",tot,ans);
}
//****************************************
int main()
{
int cas;
scanf("%d",&cas);
int T=1;
while(cas--)
{
scanf("%d",&n);
memset(node,0,sizeof(node));
for(int i=0; i<n; i++)
num[i]=in();
multiset<int>myset;
myset.clear();
int mi_ma;
int ma_mi;
myset.insert(num[0]);
for(int i=1; i<n; i++)
{
multiset<int>::iterator it;
it=myset.upper_bound(num[i]);
if(it==myset.end())
{
it--;
node[*it][1]=num[i];
}
else if(it==myset.begin())
{
node[*it][0]=num[i];
}
else
{
ma_mi=*it;
it--;
mi_ma=*it;
if(node[mi_ma][1]==0)
node[mi_ma][1]=num[i];
else
node[ma_mi][0]=num[i];
}
myset.insert(num[i]);
}
dfs(num[0]);
scanf("%s",s);
KMP(T);
T++;
}
return 0;
}