zoukankan      html  css  js  c++  java
  • 2018 计算之道初赛第二场 阿里巴巴的手机代理商(困难)(反向可持久化Trie)

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

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

    1. 添加操作

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

    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,意思为查询当前版本 -33的版本中,以ied为结尾的单词的词频和。保证 当前版本 -− 退回版本 ge 00(00 号版本为空)。

    输入格式

    第一行读入一个整数 TT,代表数据组数。

    每组数据的第一行读入一个整数 NN 代表操作数。

    接下来 NN 行,每行形容一个操作。

    保证数据满足 1 le T le 101T10,1 le N le 10^51N105,insertupdate操作的字符串总长度之和 le 10^6106,所有字符串长度 le 10^6106,输入只有小写字母。

    输出格式

    输出题目中要求的结果。

    样例说明

    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。

    被不成功不算更新版本坑了。。好气哦。。改一下就过了。

      1 #include<bits/stdc++.h>
      2 #define clr(x) memset(x,0,sizeof(x))
      3 #define clr_1(x) memset(x,-1,sizeof(x))
      4 #define mod 7
      5 #define LL long long
      6 #define INF 0x3f3f3f3f
      7 #define mp make_pair
      8 #define pb push_back
      9 #define mp make_pair
     10 #define fi first
     11 #define se second
     12 using namespace std;
     13 const int N=1e6+10;
     14 struct node
     15 {
     16     int next[26];
     17     LL num,ende;
     18 }trie[3*N];
     19 stack<int> sta;
     20 set<int> used;
     21 int root[N],nowv,dt;
     22 int makenode()
     23 {
     24     int tot=sta.top();
     25     sta.pop();
     26     used.insert(tot);
     27     return tot;
     28 }
     29 int makenode(int i)
     30 {
     31     int tot=sta.top();
     32     sta.pop();
     33     used.insert(tot);
     34     trie[tot]=trie[i];
     35     return tot;
     36 }
     37 void delnode(int i)
     38 {
     39     used.erase(i);
     40     sta.push(i);
     41     return ;
     42 }
     43 char s[N],s2[N];
     44 void add(char *s,LL d,int &root)
     45 {
     46     root=makenode(root);
     47     int now=root,len=strlen(s),p;
     48     for(int i=len-1;i>=0;i--)
     49     {
     50         p=s[i]-'a';
     51         if(!trie[now].next[p])
     52             trie[now].next[p]=makenode();
     53         else
     54             trie[now].next[p]=makenode(trie[now].next[p]);
     55         now=trie[now].next[p];
     56         trie[now].num+=d;
     57     }
     58     trie[now].ende+=d;
     59     return ;
     60 }
     61 int pt[N];
     62 bool deleted(char *s,int &root)
     63 {
     64     root=makenode(root);
     65     LL d;
     66     int now=root,len=strlen(s),p;
     67     for(int i=len-1;i>=0;i--)
     68     {
     69         p=s[i]-'a';
     70         if(!trie[now].next[p])
     71             return false;
     72         now=trie[now].next[p];
     73     }
     74     if(trie[now].ende==0)
     75         return false;
     76     d=trie[now].ende;
     77     now=root;
     78     for(int i=len-1;i>=0;i--)
     79     {
     80         p=s[i]-'a';
     81         trie[now].next[p]=makenode(trie[now].next[p]);
     82         now=trie[now].next[p];
     83         trie[now].num-=d;
     84         pt[i]=now;
     85     }
     86     trie[now].ende=0;
     87     pt[len]=root;
     88     for(int i=0;i<len;i++)
     89     {
     90         if(trie[pt[i]].num>0)
     91             break;
     92         trie[pt[i+1]].next[s[i]-'a']=0;
     93         delnode(pt[i]);
     94     }
     95     return true;
     96 }
     97 LL query(char *s,int &root)
     98 {
     99     int now=root,len=strlen(s),p;
    100     for(int i=len-1;i>=0;i--)
    101     {
    102         p=s[i]-'a';
    103         if(!trie[now].next[p])
    104             return 0;
    105         now=trie[now].next[p];
    106     }
    107     return trie[now].num;
    108 }
    109 int update(char *s1,char *s2,int &root)
    110 {
    111     root=makenode(root);
    112     int now=root,len=strlen(s1),p;
    113     for(int i=len-1;i>=0;i--)
    114     {
    115         p=s1[i]-'a';
    116         if(!trie[now].next[p])
    117             return 1;
    118         now=trie[now].next[p];
    119     }
    120     if(trie[now].num==0)
    121         return 1;
    122     LL d=trie[now].num;
    123     now=root;
    124     len=strlen(s2);
    125     bool flag=0;
    126     for(int i=len-1;i>=0;i--)
    127     {
    128         p=s2[i]-'a';
    129         if(!trie[now].next[p])
    130         {
    131             flag=1;
    132             break;
    133         }
    134         now=trie[now].next[p];
    135     }
    136     if(flag==0)
    137         return 2;
    138     now=root;
    139     len=strlen(s1);
    140     for(int i=len-1;i>0;i--)
    141     {
    142         p=s1[i]-'a';
    143         trie[now].next[p]=makenode(trie[now].next[p]);
    144         now=trie[now].next[p];
    145         trie[now].num-=d;
    146         pt[i]=now;
    147     }
    148     int pt1=trie[now].next[s1[0]-'a'];
    149     trie[now].next[s1[0]-'a']=0;
    150     pt[len]=root;
    151     for(int i=1;i<len;i++)
    152     {
    153         if(trie[pt[i]].num>0)
    154             break;
    155         trie[pt[i+1]].next[s[i]-'a']=0;
    156         delnode(pt[i]);
    157     }
    158     now=root;
    159     len=strlen(s2);
    160     for(int i=len-1;i>0;i--)
    161     {
    162         p=s2[i]-'a';
    163         if(!trie[now].next[p])
    164             trie[now].next[p]=makenode();
    165         else
    166             trie[now].next[p]=makenode(trie[now].next[p]);
    167         now=trie[now].next[p];
    168         trie[now].num+=d;
    169     }
    170     int pt2=now;
    171     trie[pt2].next[s2[0]-'a']=pt1;
    172     return 0;
    173 }
    174 int T,n,m;
    175 LL d;
    176 int main()
    177 {
    178     scanf("%d",&T);
    179     for(int i=1;i<=3000000;i++)
    180         sta.push(i);
    181     while(T--)
    182     {
    183         root[0]=0;
    184         nowv=0;
    185         memset(&trie[0],0,sizeof(trie[0]));
    186         scanf("%d",&n);
    187         for(int i=1;i<=n;i++)
    188         {
    189             scanf("%s",s);
    190             if(strcmp(s,"insert")==0)
    191             {
    192                 scanf("%s%lld",s,&d);
    193                 ++nowv;
    194                 add(s,d,root[nowv]=root[nowv-1]);
    195             }
    196             else if(strcmp(s,"delete")==0)
    197             {
    198                 scanf("%s",s);
    199                 ++nowv;
    200                 if(!deleted(s,root[nowv]=root[nowv-1]))
    201                 {
    202                     printf("Empty
    ");
    203                     nowv--;
    204                 }
    205 
    206             }
    207             else if(strcmp(s,"query")==0)
    208             {
    209                 scanf("%s",s);
    210                 printf("%lld
    ",query(s,root[nowv]));
    211             }
    212             else if(strcmp(s,"update")==0)
    213             {
    214                 scanf("%s%s",s,s2);
    215                 nowv++;
    216                 int k=update(s,s2,root[nowv]=root[nowv-1]);
    217                 if(k==1)
    218                 {
    219                     printf("Empty
    ");
    220                     nowv--;
    221                 }
    222                 if(k==2)
    223                 {
    224                     printf("Conflict
    ");
    225                     nowv--;
    226                 }
    227             }
    228             else if(strcmp(s,"vquery")==0)
    229             {
    230                 scanf("%s%d",s,&dt);
    231                 printf("%lld
    ",query(s,root[nowv-dt]));
    232             }
    233         }
    234         for(auto p:used)
    235         {
    236             memset(&trie[p],0,sizeof(trie[p]));
    237             sta.push(p);
    238         }
    239         used.clear();
    240     }
    241     return 0;
    242 }
    View Code
  • 相关阅读:
    MySQL数据表类型 = 存储引擎类型
    删除链表节点
    链表逆序(反转)
    腾讯2012笔试题
    MysqL数据表类型
    进程间的通信方式
    网络套接字编程学习笔记一
    HTTP报头
    C语言排序算法
    交换排序经典的冒泡排序算法总结
  • 原文地址:https://www.cnblogs.com/wujiechao/p/9034231.html
Copyright © 2011-2022 走看看