2018 计算之道初赛第二场 阿里巴巴的手机代理商(困难)(反向可持久化Trie)
阿里巴巴的手机代理商(困难)
阿里巴巴的手机代理商正在研究 infra 输入法的新功能。他们需要分析单词频率以改进用户输入法的体验。于是需要你在系统内核里面写一个 API。 API 有如下功能:
添加操作
添加操作格式为
insert barty 8
,意思为插入barty
这个单词,这个单词词频为 88 次。注意如果再次添加insert barty 8
操作时,就会将词频增加为 1616 次。(不会出现词频 \le 0≤0 的情况)。删除操作
删除操作格式为
delete barty
,意思为删除所有barty
这个单词。如果当前没有删除的词汇,输出
Empty
并不计入版本号。查询操作
查询操作格式为
query ty
,意思为查询当前版本以ty
结尾的单词词频总和。修改操作
修改操作格式为
update ty tied
,意思为将所有结尾是ty
的单词更新为tied
结尾,比如barty
会变为bartied
。如果不存在以ty
结尾的单词,输出Empty
。如果已经存在以tied
结尾的单词,那么说明存在 conflict。不做合并,输出Conflict
并且不算做新版本。如果既不存在ty
结尾的单词,也已经存在以tied
结尾的单词,则输出Empty
。旧版本查询操作
将操作 11,22,44 每次迭代更新都视为一个版本。版本间查询格式为
vquery ied 3
,意思为查询当前版本 -3−3的版本中,以ied
为结尾的单词的词频和。保证 当前版本 -− 退回版本 \ge 0≥0(00 号版本为空)。
输入格式
第一行读入一个整数 TT,代表数据组数。
每组数据的第一行读入一个整数 NN 代表操作数。
接下来 NN 行,每行形容一个操作。
保证数据满足 1 \le T \le 101≤T≤10,1 \le N \le 10^51≤N≤105,insert
和update
操作的字符串总长度之和 \le 10^6≤106,所有字符串长度 \le 10^6≤106,输入只有小写字母。
输出格式
输出题目中要求的结果。
样例说明
insert barty 8
之后生成版本 11。
update ty tied
之后生成版本 22。
insert party 9
之后生成版本 33。
delete barty
之后生成版本 44。
样例输入
1
10
insert barty 8
delete shawn
update ty tied
query tied
insert party 9
update y ed
query ty
delete party
vquery ied 2
vquery ed 1
样例输出
Empty
8
Conflict
9
8
8
题目来源
因为找结尾嘛,所以我们反向存string到Trie里,然后涉及多版本问题,怕空间不够用,写可持久化的时候加入了数组分配,拿个stack和set去动态分配。反正代码写完真长,debug一天2333。
被不成功不算更新版本坑了。。好气哦。。改一下就过了。
#include<bits/stdc++.h>
#define clr(x) memset(x,0,sizeof(x))
#define clr_1(x) memset(x,-1,sizeof(x))
#define mod 7
#define LL long long
#define INF 0x3f3f3f3f
#define mp make_pair
#define pb push_back
#define mp make_pair
#define fi first
#define se second
using namespace std;
const int N=1e6+;
struct node
{
int next[];
LL num,ende;
}trie[*N];
stack<int> sta;
set<int> used;
int root[N],nowv,dt;
int makenode()
{
int tot=sta.top();
sta.pop();
used.insert(tot);
return tot;
}
int makenode(int i)
{
int tot=sta.top();
sta.pop();
used.insert(tot);
trie[tot]=trie[i];
return tot;
}
void delnode(int i)
{
used.erase(i);
sta.push(i);
return ;
}
char s[N],s2[N];
void add(char *s,LL d,int &root)
{
root=makenode(root);
int now=root,len=strlen(s),p;
for(int i=len-;i>=;i--)
{
p=s[i]-'a';
if(!trie[now].next[p])
trie[now].next[p]=makenode();
else
trie[now].next[p]=makenode(trie[now].next[p]);
now=trie[now].next[p];
trie[now].num+=d;
}
trie[now].ende+=d;
return ;
}
int pt[N];
bool deleted(char *s,int &root)
{
root=makenode(root);
LL d;
int now=root,len=strlen(s),p;
for(int i=len-;i>=;i--)
{
p=s[i]-'a';
if(!trie[now].next[p])
return false;
now=trie[now].next[p];
}
if(trie[now].ende==)
return false;
d=trie[now].ende;
now=root;
for(int i=len-;i>=;i--)
{
p=s[i]-'a';
trie[now].next[p]=makenode(trie[now].next[p]);
now=trie[now].next[p];
trie[now].num-=d;
pt[i]=now;
}
trie[now].ende=;
pt[len]=root;
for(int i=;i<len;i++)
{
if(trie[pt[i]].num>)
break;
trie[pt[i+]].next[s[i]-'a']=;
delnode(pt[i]);
}
return true;
}
LL query(char *s,int &root)
{
int now=root,len=strlen(s),p;
for(int i=len-;i>=;i--)
{
p=s[i]-'a';
if(!trie[now].next[p])
return ;
now=trie[now].next[p];
}
return trie[now].num;
}
int update(char *s1,char *s2,int &root)
{
root=makenode(root);
int now=root,len=strlen(s1),p;
for(int i=len-;i>=;i--)
{
p=s1[i]-'a';
if(!trie[now].next[p])
return ;
now=trie[now].next[p];
}
if(trie[now].num==)
return ;
LL d=trie[now].num;
now=root;
len=strlen(s2);
bool flag=;
for(int i=len-;i>=;i--)
{
p=s2[i]-'a';
if(!trie[now].next[p])
{
flag=;
break;
}
now=trie[now].next[p];
}
if(flag==)
return ;
now=root;
len=strlen(s1);
for(int i=len-;i>;i--)
{
p=s1[i]-'a';
trie[now].next[p]=makenode(trie[now].next[p]);
now=trie[now].next[p];
trie[now].num-=d;
pt[i]=now;
}
int pt1=trie[now].next[s1[]-'a'];
trie[now].next[s1[]-'a']=;
pt[len]=root;
for(int i=;i<len;i++)
{
if(trie[pt[i]].num>)
break;
trie[pt[i+]].next[s[i]-'a']=;
delnode(pt[i]);
}
now=root;
len=strlen(s2);
for(int i=len-;i>;i--)
{
p=s2[i]-'a';
if(!trie[now].next[p])
trie[now].next[p]=makenode();
else
trie[now].next[p]=makenode(trie[now].next[p]);
now=trie[now].next[p];
trie[now].num+=d;
}
int pt2=now;
trie[pt2].next[s2[]-'a']=pt1;
return ;
}
int T,n,m;
LL d;
int main()
{
scanf("%d",&T);
for(int i=;i<=;i++)
sta.push(i);
while(T--)
{
root[]=;
nowv=;
memset(&trie[],,sizeof(trie[]));
scanf("%d",&n);
for(int i=;i<=n;i++)
{
scanf("%s",s);
if(strcmp(s,"insert")==)
{
scanf("%s%lld",s,&d);
++nowv;
add(s,d,root[nowv]=root[nowv-]);
}
else if(strcmp(s,"delete")==)
{
scanf("%s",s);
++nowv;
if(!deleted(s,root[nowv]=root[nowv-]))
{
printf("Empty\n");
nowv--;
} }
else if(strcmp(s,"query")==)
{
scanf("%s",s);
printf("%lld\n",query(s,root[nowv]));
}
else if(strcmp(s,"update")==)
{
scanf("%s%s",s,s2);
nowv++;
int k=update(s,s2,root[nowv]=root[nowv-]);
if(k==)
{
printf("Empty\n");
nowv--;
}
if(k==)
{
printf("Conflict\n");
nowv--;
}
}
else if(strcmp(s,"vquery")==)
{
scanf("%s%d",s,&dt);
printf("%lld\n",query(s,root[nowv-dt]));
}
}
for(auto p:used)
{
memset(&trie[p],,sizeof(trie[p]));
sta.push(p);
}
used.clear();
}
return ;
}
2018 计算之道初赛第二场 阿里巴巴的手机代理商(困难)(反向可持久化Trie)的更多相关文章
- 2019 计蒜之道 初赛 第二场 B. 百度AI小课堂-上升子序列(简单) ( 实现)
题目背景 91029102 年 99 月 22 日,百度在 X 市 XX 中学举办的第一场 AI 知识小课堂大获好评!同学们对矩阵的掌握非常棒. 今天的 AI 知识小课堂的第二场开讲啦.本场 AI ...
- 2019 计蒜之道 初赛 第二场 A 百度AI小课堂-矩阵问题 ( 等差数列求和公式)
题目背景 91029102 年 99 月 11 日,百度在 X 市 XX 中学举办了一场 AI 知识小课堂,本场 AI 知识小课堂老师教授了一些矩阵的相关知识,因为矩阵在 AI 人工智能中也有相当的 ...
- 2018 计蒜之道-初赛 第一场 A-百度无人车
百度一共制造了 nn 辆无人车,其中第 ii 辆车的重量为 a_i\ \mathrm{kg}ai kg. 由于车辆过重会增大轮胎的磨损程度,现在要给这 nn 辆车减轻重量.每将一辆车减轻 1\ \m ...
- 动态规划-hdoj-4832-百度之星2014初赛第二场
Chess Problem Description 小度和小良近期又迷上了下棋.棋盘一共同拥有N行M列,我们能够把左上角的格子定为(1,1),右下角的格子定为(N,M).在他们的规则中,"王 ...
- 计蒜之道 初赛第一场B 阿里天池的新任务(简单)
阿里“天池”竞赛平台近日推出了一个新的挑战任务:对于给定的一串 DNA 碱基序列 tt,判断它在另一个根据规则生成的 DNA 碱基序列 ss 中出现了多少次. 首先,定义一个序列 ww: \displ ...
- 2017 计蒜之道 初赛 第一场 A、B题
A题 阿里的新游戏 题目概述: 阿里九游开放平台近日上架了一款新的益智类游戏——成三棋.成三棋是我国非常古老的一个双人棋类游戏,其棋盘如下图所示: 成三棋的棋盘上有很多条线段,只能在线段交叉点上放入棋 ...
- 2014百度之星初赛第二场hdu 4831 Scenic Popularity
Scenic Popularity Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others ...
- 2013腾讯编程马拉松初赛第二场(3月22日) 小Q系列故事——为什么时光不能倒流 ---好水!!
我以为我会是最坚强的那一个 我还是高估了自己 我以为你会是最无情的那一个 还是我贬低了自己 就算不能够在一起 我还是为你担心 就算你可能听不清 也代表我的心意 那北极星的眼泪 闪过你曾经的眼角迷离 那 ...
- hihocoder 微软编程之美2015 初赛 第二场(暴力+字典序+图论+思维算法)
题目1 : 扑克牌 时间限制:2000ms 单点时限:1000ms 内存限制:256MB 描述 一副不含王的扑克牌由52张牌组成,由红桃.黑桃.梅花.方块4组牌组成,每组13张不同的面值.现在给定52 ...
随机推荐
- GD库imagecopyresampled()方法详解~
整理了一下GD库这个缩放,拉伸复制的方法 因为这个函数参数太多了~ imagecopyresampled() /* //拷贝部分图像并调整大小 bool imagecopyresampled ( ...
- JFinal向客户端渲染图片的方法
JFinal提供了好几种方便的render但是不知道为啥就是没有提供直接渲染图片的render,如果我们直接在Controller的方法中往输入流中写的话是还是会有默认的render生效的,比如下面这 ...
- VC调用易语言DLL
易语言方面: .版本 .子程序 show, , 公开 ' 本名称子程序用作测试程序用,仅在开发及调试环境中有效,编译发布程序前将被系统自动清空,请将所有用作测试的临时代码放在本子程序中. ***注意不 ...
- python进阶之关键字和运算符触发魔法方法
前言 python有众多的魔法方法,它们会在满足某种条件下触发执行,掌握好魔法方法的使用,可以加快程序的运行效率,同时减少逻辑调用. 关键字与魔法方法 python的一些魔法方法是关键字触发的,即py ...
- Android :ExpandableListActivity
http://developer.android.com/reference/android/app/ExpandableListActivity.html# public class Expanda ...
- python 协程嵌套
import asyncio import time now = lambda: time.time() async def do_some_work(x): print('Waiting: ', x ...
- caffe Python API 之Accuracy
net.acc = caffe.layers.Accuracy(net.fc3,net.label) 输出: layer { name: "acc" type: "Acc ...
- C语言使用数学库编译不通过问题
#include <stdio.h>#include <math.h> int main(){ double a = 10.0,b = 3.0; f ...
- MyBatis3-与Spring MVC 4集成
继前一篇的例子http://www.cnblogs.com/EasonJim/p/7052388.html,已经集成了Spring框架,现在将改造成Spring MVC的项目,并实现如下功能: 1.不 ...
- JAVA封装消息中间件调用一(kafka生产者篇)
这段时间因为工作关系一直在忙于消息中间件的发开,现在趁着项目收尾阶段分享下对kafka的一些使用心得. kafka的原理我这里就不做介绍了,可参考http://orchome.com/kafka/in ...