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
  • 相关阅读:
    171. Excel Sheet Column Number (Easy)
    349. Intersection of Two Arrays (Easy)
    453. Minimum Moves to Equal Array Elements (Easy)
    657. Judge Route Circle (Easy)
    CSS笔记
    保存页面状态
    UI开发总结
    ubuntu 下配置munin
    反向代理配置
    JavaScript 高级程序设计第二版
  • 原文地址:https://www.cnblogs.com/wujiechao/p/9034231.html
Copyright © 2011-2022 走看看