阿里巴巴的手机代理商(困难)

阿里巴巴的手机代理商正在研究 infra 输入法的新功能。他们需要分析单词频率以改进用户输入法的体验。于是需要你在系统内核里面写一个 API。 API 有如下功能:

  1. 添加操作

    添加操作格式为insert barty 8 ,意思为插入barty这个单词,这个单词词频为 88 次。注意如果再次添加insert barty 8操作时,就会将词频增加为 1616 次。(不会出现词频 \le 0≤0 的情况)。

  2. 删除操作

    删除操作格式为delete barty,意思为删除所有barty这个单词。

    如果当前没有删除的词汇,输出Empty并不计入版本号。

  3. 查询操作

    查询操作格式为query ty,意思为查询当前版本以ty结尾的单词词频总和。

  4. 修改操作

    修改操作格式为update ty tied,意思为将所有结尾是ty的单词更新为tied结尾,比如barty会变为bartied。如果不存在以ty结尾的单词,输出Empty。如果已经存在以tied结尾的单词,那么说明存在 conflict。不做合并,输出Conflict并且不算做新版本。如果既不存在ty结尾的单词,也已经存在以tied结尾的单词,则输出Empty。

  5. 旧版本查询操作

    将操作 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

题目来源

2018 计蒜之道 初赛 第二场


因为找结尾嘛,所以我们反向存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)的更多相关文章

  1. 2019 计蒜之道 初赛 第二场 B. 百度AI小课堂-上升子序列(简单) ( 实现)

    题目背景 ​91029102 年 99 月 22 日,百度在 X 市 XX 中学举办的第一场 AI 知识小课堂大获好评!同学们对矩阵的掌握非常棒. 今天的 AI 知识小课堂的第二场开讲啦.本场 AI ...

  2. 2019 计蒜之道 初赛 第二场 A 百度AI小课堂-矩阵问题 ( 等差数列求和公式)

    题目背景 ​91029102 年 99 月 11 日,百度在 X 市 XX 中学举办了一场 AI 知识小课堂,本场 AI 知识小课堂老师教授了一些矩阵的相关知识,因为矩阵在 AI 人工智能中也有相当的 ...

  3. 2018 计蒜之道-初赛 第一场 A-百度无人车

    百度一共制造了 nn 辆无人车,其中第 ii 辆车的重量为 a_i\ \mathrm{kg}ai​ kg. 由于车辆过重会增大轮胎的磨损程度,现在要给这 nn 辆车减轻重量.每将一辆车减轻 1\ \m ...

  4. 动态规划-hdoj-4832-百度之星2014初赛第二场

    Chess Problem Description 小度和小良近期又迷上了下棋.棋盘一共同拥有N行M列,我们能够把左上角的格子定为(1,1),右下角的格子定为(N,M).在他们的规则中,"王 ...

  5. 计蒜之道 初赛第一场B 阿里天池的新任务(简单)

    阿里“天池”竞赛平台近日推出了一个新的挑战任务:对于给定的一串 DNA 碱基序列 tt,判断它在另一个根据规则生成的 DNA 碱基序列 ss 中出现了多少次. 首先,定义一个序列 ww: \displ ...

  6. 2017 计蒜之道 初赛 第一场 A、B题

    A题 阿里的新游戏 题目概述: 阿里九游开放平台近日上架了一款新的益智类游戏——成三棋.成三棋是我国非常古老的一个双人棋类游戏,其棋盘如下图所示: 成三棋的棋盘上有很多条线段,只能在线段交叉点上放入棋 ...

  7. 2014百度之星初赛第二场hdu 4831 Scenic Popularity

    Scenic Popularity Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others ...

  8. 2013腾讯编程马拉松初赛第二场(3月22日) 小Q系列故事——为什么时光不能倒流 ---好水!!

    我以为我会是最坚强的那一个 我还是高估了自己 我以为你会是最无情的那一个 还是我贬低了自己 就算不能够在一起 我还是为你担心 就算你可能听不清 也代表我的心意 那北极星的眼泪 闪过你曾经的眼角迷离 那 ...

  9. hihocoder 微软编程之美2015 初赛 第二场(暴力+字典序+图论+思维算法)

    题目1 : 扑克牌 时间限制:2000ms 单点时限:1000ms 内存限制:256MB 描述 一副不含王的扑克牌由52张牌组成,由红桃.黑桃.梅花.方块4组牌组成,每组13张不同的面值.现在给定52 ...

随机推荐

  1. Redis数据类型之散列(hash)

    1. 什么是散列 散列类似于一个字典,是一个<K, V>对的集合,不过这个key和value都只能是字符串类型的,不能嵌套,可以看做Java中的Map<String, String& ...

  2. php常用函数——数学函数

    php常用函数——数学函数

  3. Java源码-HashMap(jdk1.8)

    一.hash方法 如下是jdk1.8中的源码 static final int hash(Object key) { int h; return (key == null) ? 0 : (h = ke ...

  4. Qualcom QMI系列-基本知识介绍(转)

    1 引言1.1 编写目的       介绍Qualcom QMI 基本知识,API使用,设计原理,基于QMI的RemoteEfs(NV)分析1.2 阅读建议       高通平台入门1.3 参考资料 ...

  5. 在64位ubuntu中安装代码比较工具beyond compare

    1,//从http://www.scootersoftware.com/download.php 官方地址下载 bcompare-3.3.2.14050.tar.gz 或 bcompare-4.0.7 ...

  6. PHP 不让标准浏览器(firfox,chrome等)走浏览器的缓存页面

    或在HTML页面里加: <META HTTP-EQUIV="Cache-Control" CONTENT="no-cache,no-store, must-reva ...

  7. Android仿新浪新闻SlidingMenu界面的实现 .

    先看看原图: 如图所示,这种侧滑效果以另一种方式替代了原先tab导航的那种用户体验方式 给人耳目一新的感觉,现已被广大知名应用所效仿,如新浪新闻,网易新闻,人人网等 那么这种效果该如何实现呢?那就需要 ...

  8. JVM内存分配及GC简述

    在阐述JVM的内存区域之前,先来看下计算机的存储单位.从小到大依次为Bit,Byte,KB,MB,GB,TB.相邻的单位相差2的10次方. 计算机运行中的存储元件主要分为寄存器(位于CPU)和内存,寄 ...

  9. win10产品密钥 win10专业版激活码key

    转载地址:http://www.xitongcheng.com/jiaocheng/xtazjc_article_35407.html https://blog.csdn.net/WangJianku ...

  10. Nginx 原理篇

    前言 在学习 Nginx 之前,我们首先有必要搞清楚下面几个问题: 1. Web服务器是怎么工作的? 2. Apache 与 Nginx 有何异同? 3. Nginx 工作模式是怎样的? 下面就围绕这 ...