阿里巴巴的手机代理商正在研究 infra 输入法的新功能。他们需要分析单词频率以改进用户输入法的体验。于是需要你在系统内核里面写一个 API。 API 有如下功能:
添加操作
添加操作格式为
insert barty 8
,意思为插入barty
这个单词,这个单词词频为 88 次。注意如果再次添加insert barty 8
操作时,就会将词频增加为 1616 次。(不会出现词频 \le 0≤0 的情况)。删除操作
删除操作格式为
delete barty
,意思为删除所有barty
这个单词。如果当前没有删除的词汇,输出
Empty
。查询操作
查询操作格式为
query ty
,意思为查询当前版本以ty
结尾的单词词频总和。
输入格式
第一行读入一个整数 TT,代表数据组数。
每组数据的第一行读入一个整数 NN 代表操作数。
接下来 NN 行,每行形容一个操作。
保证数据满足 1 \le T \le 101≤T≤10,1 \le N \le 10001≤N≤1000,insert
操作的字符串总长度之和 \le 3000≤3000,所有字符串长度 \le 10000≤10000,输入只有小写字母。
输出格式
输出题目中要求的结果。
样例输入
1 6 insert barty 8 query ty insert party 9 query ty delete barty query ty
样例输出
8 17 9
题目来源
题解:当时做的时候,没做出来,细节没处理好。看到很多大佬都用逆序字典树。这里我用的map<sting,int>,也可以,代码也更短。m存逆序所有的单词或者字母,m2存入输入的单词本体。insert对输入的单词逆序截取子串加x,就是删除的时候要特别小心,首先要判断这个本体单词出现过没,不能判断m2里面存入的单词,比如part 删除art 逆序的时候存入过m2,会删除单词,而不是输出empty呢。所以m2存本体的用法在这里,删除的时候把本体置为0,然后依次对m里面的所有( 以这个单词结尾的都要减去这个值。对着代码好理解一些。
AC代码:
#include<bits/stdc++.h> using namespace std; map<string,int>m,m2;///m存逆序所有的单词或者字母,m2存入输入的单词本体 int main() { int t,n,x; string s,a; cin>>t; while(t--) { m.clear(); m2.clear(); cin>>n; for(int i=0; i<n; i++) { cin>>s>>a; if(s=="insert") { cin>>x,m2[a]+=x; for(int j=a.size()-1; j>=0; j--) m[a.substr(j,a.size()-j)]+=x; } else if(s=="delete") { if(!m2[a]) { puts("Empty"); continue; } int num=m2[a]; m2[a]=0; for(int j=a.size()-1; j>=0; j--) m[a.substr(j,a.size()-j)]-=num; } else cout<<m[a]<<endl; } } return 0; }