阿里巴巴的手机代理商(简单)
阿里巴巴的手机代理商正在研究 infra 输入法的新功能。他们需要分析单词频率以改进用户输入法的体验。于是需要你在系统内核里面写一个 API。 API 有如下功能:
添加操作
添加操作格式为
insert barty 8
,意思为插入barty
这个单词,这个单词词频为 88 次。注意如果再次添加insert barty 8
操作时,就会将词频增加为 1616 次。(不会出现词频\le 0≤0 的情况)。删除操作
删除操作格式为
delete barty
,意思为删除所有barty
这个单词。如果当前没有删除的词汇,输出
Empty
。查询操作
查询操作格式为
query ty
,意思为查询当前版本以ty
结尾的单词词频总和。
输入格式
第一行读入一个整数 T,代表数据组数。
每组数据的第一行读入一个整数 N代表操作数。
接下来 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几率这个单词的频率,然后对应每个位置减掉这个单词所有的频率.查询操作就是不断的从后循环查找这个单词的第一个字母对应的频率,然后返回回来。
坑点:查询操作遇到没有的后缀直接返回0,不然会一直wa!!!。反正这里我错了不下10次!!!
#include <cstring>
#include <cstdio>
#include<map>
#include<string>
const int maxn=1e5+10;
using namespace std;
struct Tree
{
int data[30];
int num;
void init()
{
for(int i=0; i<=26; i++)
data[i]=-1;
num=0;
}
} T[maxn];
int cur;//每个新建的节点的下标
void Insert(char *str,int value)
{
int cnt=0;
int len=strlen(str);
for(int i=len-1; i>=0; i--)
{
int x=str[i]-'a';
if(T[cnt].data[x]==-1)//如果这个节点不存在就新建
{
T[cur].init();
T[cnt].data[x]=cur++;//data[x]保存的是这个字母后一个字母的下标
}
cnt=T[cnt].data[x];//下标移向后一个字母
T[cnt].num+=value;
}
}
void Delete(char *str,int value)
{
int x,cnt=0;
int len=strlen(str);
for(int i=len-1; i>=0; i--)
{
x=str[i]-'a';
cnt=T[cnt].data[x];
T[cnt].num-=value;
}
}
int Query(char *str)
{
int x,cnt=0;
int len=strlen(str);
for(int i=len-1; i>=0; i--)
{
x=str[i]-'a';
if(T[cnt].data[x]==-1)//没有这个一直wa
return 0;
cnt=T[cnt].data[x];
}
return T[cnt].num;
}
char op[maxn],s[maxn];
int main()
{
int t,n;
scanf("%d",&t);
while(t--)
{
cur=1;
T[0].init();
scanf("%d",&n);
map<string,int>mp;
while(n--)
{
int data,cnt;
scanf(" %s",op);
if(op[0]=='i')
{
scanf(" %s %d",s,&data);
mp[s]=mp[s]+data;
Insert(s,data);
}
else if(op[0]=='q')
{
scanf(" %s",s);
int ans = Query(s);
printf("%d\n",ans);
}
else
{
scanf(" %s",s);
if(mp[s]==0)
printf("Empty\n");
else
{
Delete(s,mp[s]);
mp[s]=0;
}
}
}
}
}