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

来源:互联网 发布:网络主播很溜的台词 编辑:程序博客网 时间:2024/05/17 02:55

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

然后就是在字典树上匹配

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


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


0 0
原创粉丝点击