点此看题面

大致题意: 三种操作:加入一个字符串,删除一个字符串,求最早什么时候以某个字符串为前缀的字符串个数超过给定值。

\(Trie\)

这道题显然是\(Trie\)的暴力裸题。

考虑我们对于\(Trie\)上的每个节点,开一个\(vector\),其中第\(i\)位(注意\(vector\)的下标是从\(0\)开始的)存储以这个节点所代表的字符串为前缀的字符串个数超过\(i\)的最早时间。

至于这怎么维护,只要同时再维护一下对于每个字符串当前以其为前缀的字符串个数,由于这个个数每次最多修改\(1\),因此我们只要在每次修改时比较个数与\(vector\)的\(size\),若个数超过了\(vector\)的\(size\),就在\(vector\)中\(push\_back\)当前时间。

询问时只要找到对应节点,如果\(vector\)的\(size\)大于询问的给定值\(v\),就返回\(vector\)的第\(v\)位,否则返回\(-1\)。

关于内存

一开始,我很自信的把数组开到了\(10^5*60\),又由于没看见题目中说只有前十个小写字母,所以就完美地\(MLE\)了......

然后想了想发现\(Trie\)的数组是显然用不满的,但究竟该开多大呢?

思索半天没有结果,一狠心便去学了发指针实现\(Trie\),然后写完调了调\(bug\),就过了此题。

看看此时内存,仅有\(40.58MB\),真是无语......

代码

#include<bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define Reg register
#define RI Reg int
#define Con const
#define CI Con int&
#define I inline
#define W while
#define N 100000
#define K 60
using namespace std;
class FastIO
{
private:
#define FS 100000
#define tc() (A==B&&(B=(A=FI)+fread(FI,1,FS,stdin),A==B)?EOF:*A++)
#define pc(c) (C==E&&(clear(),0),*C++=c)
#define tn (x<<3)+(x<<1)
#define D isdigit(c=tc())
int T;char c,*A,*B,*C,*E,FI[FS],FO[FS],S[FS];
public:
I FastIO() {A=B=FI,C=FO,E=FO+FS;}
Tp I void read(Ty& x) {x=0;W(!D);W(x=tn+(c&15),D);}
Ts I void read(Ty& x,Ar&... y) {read(x),read(y...);}
I void reads(string& x) {x="";W(isspace(c=tc()));W(x+=c,!isspace(c=tc())&&~c);}
Tp I void write(Ty x) {x<0&&(pc('-'),x=-x);W(S[++T]=x%10+48,x/=10);W(T) pc(S[T--]);}
Tp I void writeln(Con Ty& x) {write(x),pc('\n');}
I void clear() {fwrite(FO,1,C-FO,stdout),C=FO;}
}F;
class Trie//指针实现Trie
{
private:
struct node
{
int V;node *S[10];vector<int> P;
I node() {V=0,P.clear();for(RI i=0;i^10;++i) S[i]=NULL;}//初始化清空节点,一定要写,不然会挂
}*rt;
public:
I Trie() {rt=new node;}//初始化根节点
I void Upt(Con string& s,CI v,CI ti)//修改(插入/删除)
{
node *x=rt;for(RI i=0,l=s.length(),t;i^l;++i)
x->S[t=s[i]-97]==NULL&&(x->S[t]=new node),x=x->S[t],//如果子节点为空,新建子节点
(x->V+=v)>x->P.size()&&(x->P.push_back(ti),0);//更新vector
}
I int Qry(Con string& s,CI v)//询问
{
node *x=rt;for(RI i=0,l=s.length(),t;i^l;++i)
if(x->S[t=s[i]-97]==NULL) return -1;else x=x->S[t];//如果子节点为空,直接返回-1
return x->P.size()>v?x->P[v]:-1;//判断是否有解,有解则返回答案,否则返回-1
}
}T;
int main()
{
RI Qt,i,op,x,y,z,lst=0;string s;for(F.read(Qt),i=1;i<=Qt;++i) switch(F.read(op),op)
{
case 1:F.reads(s),T.Upt(s,1,i);break;
case 2:F.reads(s),T.Upt(s,-1,i);break;
case 3:F.reads(s),F.read(x,y,z),F.writeln(lst=T.Qry(s,(1LL*x*abs(lst)+y)%z));break;//注意1LL,我原本没写就挂成了60分
}return F.clear(),0;
}

【洛谷5335】[THUSC2016] 补退选(指针实现Trie)的更多相关文章

  1. 洛谷P5335 [THUSC2016]补退选 题解

    传送门 一道字典树的例题吧 先说下思路前1,2两个条件都易满足,字典树插入修改即可,第三个条件可用动态数组来实现,存下它的size表示当前有几个节点经过(即人数),其下标表示第几次出现,里面存入操作次 ...

  2. [BZOJ4896][THUSC2016]补退选(Trie)

    4896: [Thu Summer Camp2016]补退选 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 653  Solved: 228[Subm ...

  3. 洛谷P2922 [USACO008DEC] 秘密消息Secret Message [Trie树]

    洛谷传送门,BZOJ传送门 秘密消息Secret Message Description     贝茜正在领导奶牛们逃跑.为了联络,奶牛们互相发送秘密信息.     信息是二进制的,共有M(1≤M≤5 ...

  4. BZOJ 2734 洛谷 3226 [HNOI2012]集合选数【状压DP】【思维题】

    [题解] 思维题,看了别人的博客才会写. 写出这样的矩阵: 1,3,9,... 2,6,18,... 4,12.36,... 8,24,72,... 我们要做的就是从矩阵中选出一些数字,但是不能选相邻 ...

  5. 洛谷$P3226\ [HNOI2012]$集合选数 状压$dp$

    正解:$dp$ 解题报告: 传送门$QwQ$ 考虑列一个横坐标为比值为2的等比数列,纵坐标为比值为3的等比数列的表格.发现每个数要选就等价于它的上下左右不能选. 于是就是个状压$dp$板子了$QwQ$ ...

  6. 洛谷:P1036:选数

    题目描述 已知 nn 个整数 x1,x2,…,xnx1​,x2​,…,xn​ ,以及 11 个整数 kk ( k<nk<n ).从 nn 个整数中任选 kk 个整数相加,可分别得到一系列的 ...

  7. BZOJ4896 THUSC2016补退选(trie)

    字符串扔进trie,vector记录每个前缀出现次数的最大值的更新记录即可. #include<iostream> #include<cstdio> #include<c ...

  8. BZOJ 4896 [Thusc2016]补退选 (Trie树维护vector)

    题目大意:略 这竟然是$thusc$的题... 先把询问里加入的串全拎出来,建出$Trie$树,$Trie$里每个节点都开一个$vector$记录操作标号,再记录操作数量$sum$ 然后瞎**搞搞就行 ...

  9. 洛谷 P2073 送花 treap 无指针

    看了那么多题解都没做对,结果今早上按自己的思路和模板做了做,然后过了. 平衡树裸题 直接上代码: #include<bits/stdc++.h> #define rint register ...

随机推荐

  1. 数据库迁移导致Unknown character set: 'GBK' 应用异常

    https://blog.csdn.net/u013415591/article/details/82692242https://blog.csdn.net/gx_1_11_real/article/ ...

  2. c++ 的namespace及注意事项

    前文 下文中的出现的"当前域"为"当前作用域"的简写 namepsace在c++中是用来避免不同模块下相同名字冲突的一种关键字,本文粗略的介绍了一下namesp ...

  3. mysql5.7中timestam默认值'0000-00-00 00:00:00'报错

    在mysql5.7中设置 timestamp NOT NULL DEFAULT '0000-00-00 00:00:00'会报错: 解决办法: mysql> set sql_mode='NO_A ...

  4. 软件文档写作-plantuml画用例图和时序图

    背景 当下的软件开发人员,不可避免的需要输出一些软件设计文档,作为一个软件工程专业毕业的工程师,最常用的设计工具就是UML,使用UML工具绘制一些软件相关的图,是必备技能,也是输出的技术文档中的重要组 ...

  5. kubernetes haproxy+keepalive实现master集群高可用

    前言 master的HA,实际是apiserver的HA.Master的其他组件controller-manager.scheduler都是可以通过etcd做选举(--leader-elect),而A ...

  6. ASP.NET webform总结

    一.asp.net中的内置对象1.Page对象属性:isPostBack 回传 返回bool类型通过url访问就是首次加载,通过控件事件访问页面就是回传.二.页面的执行过程 a.每次访问页面,或访问页 ...

  7. 多线程十 Timer

    定时/计算在java中主要使用的是Timer对象,他的内部依然是采用多线程方式进行处理 它有四个构造方法 方法名 作用 Timer() 空参 Timer(String name) 指定名字 Timer ...

  8. iOS的常用类库

    target 'NewCompass' do #UI通用 pod 'SVProgressHUD' pod 'MJRefresh' pod 'SnapKit' #pod 'RTRootNavigatio ...

  9. golang中,new和make的区别

    在golang中,make和new都是分配内存的,但是它们之间还是有些区别的,只有理解了它们之间的不同,才能在合适的场合使用. 简单来说,new只是分配内存,不初始化内存: 而make即分配又初始化内 ...

  10. 面试再问ThreadLocal,别说你不会

    转载自:公众号<Java知音> ThreadLocal是什么 以前面试的时候问到ThreadLocal总是一脸懵逼,只知道有这个哥们,不了解他是用来做什么的,更不清楚他的原理了.表面上看他 ...