建一棵字典树,记一下时间
然后就是在字典树上匹配
因为匹配长度是单调增的,所以维护一个时间的单调递增栈
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<set>
#define cl(x) memset(x,0,sizeof(x))
using namespace std;
typedef long long ll;
inline char nc()
{
static char buf[100000],*p1=buf,*p2=buf;
if (p1==p2) { p2=(p1=buf)+fread(buf,1,100000,stdin); if (p1==p2) return EOF; }
return *p1++;
}
inline void read(int &x){
char c=nc(),b=1;
for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1;
for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b;
}
inline void read(char &x){
for (x=nc();x!='A' && x!='Q';x=nc());
}
struct node{
int ch[2];
int val;
}T[3200005];
int rt=1,cnt=1;
inline void add(int *s,int len,int tim){
int p=rt;
for (int i=1;i<=len;i++)
{
if (!T[p].ch[s[i]]) T[p].ch[s[i]]=++cnt;
p=T[p].ch[s[i]];
}
T[p].val=tim;
}
int Stk[1000005],pnt;
int L,R;
inline int query(int *s,int len){
int p=rt;
pnt=0;
for (int i=1;i<=len;i++)
{
if (!T[p].ch[s[i]]) break;
p=T[p].ch[s[i]];
int x=T[p].val;
if (x && x<L) pnt=0;
if (x>=L && x<=R)
{
while (pnt && Stk[pnt]>=x) pnt--;
Stk[++pnt]=x;
}
}
return pnt;
}
int str[505],icnt=0;
int clk;
int main()
{
int Q,x,len; char order;
freopen("t.in","r",stdin);
freopen("t.out","w",stdout);
read(Q);
while (Q--)
{
read(order);
if (order=='A')
{
icnt=0;
for (int i=1;i<=4;i++)
{
read(x);
for (int i=7;~i;i--)
str[++icnt]=(x>>i)&1;
}
read(len);
add(str,len,++clk);
}
else if (order=='Q')
{
icnt=0;
for (int i=1;i<=4;i++)
{
read(x);
for (int i=7;~i;i--)
str[++icnt]=(x>>i)&1;
}
read(L); read(R);
printf("%d\n",query(str,icnt));
}
}
return 0;
}