[Trie树 单调栈] BZOJ 4523 [Cqoi2016]路由表

建一棵字典树,记一下时间

然后就是在字典树上匹配

因为匹配长度是单调增的,所以维护一个时间的单调递增栈


#include
#include
#include
#include
#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 && 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;
}


你可能感兴趣的:(单调栈,字典树)