【Trie+vector】BZOJ4896(Thu Summer Camp2016)[补退选]题解
来源:互联网 发布:中文域名转码 源码 编辑:程序博客网 时间:2024/06/06 13:21
题目概述
有n个事件,分为三类:
1.插入字符串S。
2.删除字符串S。
3.求最小的pos,使第pos个事件结束后,以S为前缀的字符串个数>v。
解题报告
这种插入和删除字符串还要问前缀(而且还有强制在线)的题目我们不难想到用Trie解决。只是这个询问比较奇怪,但用STL乱搞就很容易了(滑稽:P)。
为每一个Trie节点记录一个vector,表示w分别为1,2,3,…时的最早事件编号,那么每次询问v时输出w为v+1时的最早事件编号就行了(因为每次w只会+1,所以v+1的最早事件编号绝对比>v+1的最早事件编号小),非常暴力……
但是这样vector会不会炸空间呢?不会。思考一下我们会发现只有插入的时候vector才会进入新的元素,删除是不会的(因为删除让w减小了)。而每次插入最多遍历到len(len是字符串长度)个节点,所以所有节点vector元素的总数为n*len,是可以承受的。
ps:这道题题目描述自相矛盾,没有说清楚到底是26个小写字母还是10个小写字母,不过好像用指针动态处理就没什么事了(但我还是开了10=_=)
示例程序
#include<cstdio>#include<vector>using namespace std;typedef long long LL;const int maxn=100000,maxl=60,maxt=maxn*maxl,maxi=10;int te,ans;char s[maxl+5];struct Trie{ struct node { int w,id;node* son[maxi];vector<int> que; node(int a,int b) {w=a;id=b;for (int i=0;i<maxi;i++) son[i]=0;} }; typedef node* P_node; int si;P_node ro; Trie() {si=0;ro=new node(0,0);} int ID(char ch) {return ch-'a';} void Insert(char *s,int te) { P_node pos=ro; for (int i=1;s[i];i++) { if (!pos->son[ID(s[i])]) pos->son[ID(s[i])]=new node(0,++si); pos=pos->son[ID(s[i])];pos->w++; int num=pos->que.size(); if (!num||pos->w>num) pos->que.push_back(te); //新的w出现了,把事件编号加入vector } } void Delete(char *s) { P_node pos=ro; for (int i=1;s[i];i++) pos=pos->son[ID(s[i])],pos->w--; } int Find(char *s,int v) { P_node pos=ro; for (int i=1;s[i];i++) if (!pos->son[ID(s[i])]) return -1; else pos=pos->son[ID(s[i])]; int num=pos->que.size(); if (num<=v) return -1; return pos->que[v]; //输出v+1的最小事件编号 }};Trie tr;char readc(){ static char buf[100000],*l=buf,*r=buf; if (l==r) r=(l=buf)+fread(buf,1,100000,stdin); if (l==r) return EOF; else return *l++;}bool Eoln(char ch) {return ch==10||ch==13||ch==EOF;}int reads(char *s){ int len=0;char ch=readc();if (ch==EOF) return EOF; s[++len]=ch;while ('a'<=s[len]&&s[len]<='z') s[++len]=readc(); s[len--]=0;return len;}int readi(int &x){ int tot=0,f=1;char ch=readc(),lst=ch; while ('9'<ch||ch<'0') {if (ch==EOF) return EOF;lst=ch;ch=readc();} if (lst=='-') f=-f; while ('0'<=ch&&ch<='9') tot=tot*10+ch-48,ch=readc(); x=tot*f; return Eoln(ch);}int absi(int x) {if (x<0) return -x; else return x;}int main(){ freopen("program.in","r",stdin); freopen("program.out","w",stdout); readi(te); for (int i=1;i<=te;i++) { int td;readi(td);reads(s); if (td==1) tr.Insert(s,i); else if (td==2) tr.Delete(s); else { int a,b,c;readi(a);readi(b);readi(c); printf("%d\n",ans=tr.Find(s,((LL)a*absi(ans)+b)%c)); } } return 0;}
阅读全文
0 0
- 【Trie+vector】BZOJ4896(Thu Summer Camp2016)[补退选]题解
- [Trie] BZOJ4896: [Thu Summer Camp2016]补退选
- BZOJ4896 [Thu Summer Camp2016]补退选
- BZOJ 4896 Thu Summer Camp2016 补退选 Trie树
- [Trie]BZOJ 4896——[Thu Summer Camp2016]补退选
- bzoj 4896: [Thu Summer Camp2016]补退选 字典树+vector
- 4896: [Thu Summer Camp2016]补退选
- BZOJ4897 [Thu Summer Camp2016]成绩单
- 4897: [Thu Summer Camp2016]成绩单
- [DP] BZOJ 4897 [Thu Summer Camp2016]成绩单
- BZOJ4897: [Thu Summer Camp2016]成绩单 DP
- BZOJ 4103 [Thu Summer Camp 2015]异或运算 可持久化Trie
- 【bzoj4103】 【Thu Summer Camp 2015】【异或运算】【可持久化trie】
- 【BZOJ 4103】[Thu Summer Camp 2015]异或运算 可持久化trie树
- bzoj 4103: [Thu Summer Camp 2015]异或运算 可持久化trie
- BZOJ4104 [Thu Summer Camp 2015]解密运算
- [BZOJ4105][Thu Summer Camp 2015]平方运算
- 4104: [Thu Summer Camp 2015]解密运算
- Linux----使用GDB调试多进程和多线程程序
- Windows平台下python2和3的兼容问题解决
- 进程 线程 协程 管程 纤程 概念对比理解
- 自我对Map的使用方法总结与归纳!
- 背景建模/背景减除/前景提取之背景建模库
- 【Trie+vector】BZOJ4896(Thu Summer Camp2016)[补退选]题解
- caffe添加PrecisionRecallLosslayer层(一)
- Flex中使用DataGrid
- Python基础-字符串格式化_百分号方式_format方式
- 字典序位置
- C语言中的单链表面试题----基础
- cookie的简介
- 常用图形图像算法总结
- Web 开发者学习路线图