• codeforces 666E. Forensic Examination(广义后缀自动机,Parent树,线段树合并)


    传送门:

    解题思路:

    很坑的一道题,需要离线处理,假如只有一组询问,那么就可以直接将endpos集合直接累加输出就好了。

    这里就要将询问挂在树节点上,在进行线段树合并时查询就好了。

    代码超级容易写挂的。

    注意要将匹配串时尽量找到最浅根,易于统计答案。

    倍增处理就好了。

    代码:

      1 #include<cstdio>
      2 #include<vector>
      3 #include<cstring>
      4 #include<algorithm>
      5 const int N=1000000;
      6 struct int_2{
      7     int vl;
      8     int ps;
      9 }imt;
     10 struct sant{
     11     int tranc[26];
     12     int len;
     13     int pre;
     14 }s[N];
     15 struct pnt{
     16     int hd;
     17     int fa[24];
     18     int rt;
     19     std::vector<int>posquery;
     20 }p[N];
     21 struct ent{
     22     int twd;
     23     int lst;
     24 }e[N];
     25 struct trnt{
     26     int ls;
     27     int rs;
     28     int_2 val;
     29 }tr[N<<2];
     30 struct qnt{
     31     int l;
     32     int r;
     33     int pl;
     34     int pr;
     35     int lt;
     36     int pos;
     37     int_2 ans;
     38     void Insert(void)
     39     {
     40         scanf("%d%d%d%d",&l,&r,&pl,&pr);
     41         lt=pr-pl+1;
     42         return ;
     43     }
     44 }q[N];
     45 char tmp[N];
     46 char str[N];
     47 std::vector<int>lpnt[N];
     48 int n,m,Q;
     49 int siz;
     50 int fin;
     51 int cnt;
     52 int tnt;
     53 void ade(int f,int t)
     54 {
     55     cnt++;
     56     e[cnt].twd=t;
     57     e[cnt].lst=p[f].hd;
     58     p[f].hd=cnt;
     59     return ;
     60 }
     61 int_2 max(int_2 x,int_2 y)
     62 {
     63     if(x.vl!=y.vl)
     64         return x.vl>y.vl?x:y;
     65     return x.ps<y.ps?x:y;
     66 }
     67 void pushup(int spc)
     68 {
     69     tr[spc].val=max(tr[tr[spc].ls].val,tr[tr[spc].rs].val);
     70     return ;
     71 }
     72 void update(int l,int r,int &spc,int pos)
     73 {
     74     if(!spc)
     75         spc=++tnt;
     76     if(l==r)
     77     {
     78         tr[spc].val.vl++;
     79         tr[spc].val.ps=pos;
     80         return ;
     81     }
     82     int mid=(l+r)>>1;
     83     if(pos<=mid)
     84         update(l,mid,tr[spc].ls,pos);
     85     else
     86         update(mid+1,r,tr[spc].rs,pos);
     87     pushup(spc);
     88     return ;
     89 }
     90 void merge(int &spc1,int spc2)
     91 {
     92     if(!spc1||!spc2)
     93     {
     94         spc1|=spc2;
     95         return ;
     96     }
     97     if(!tr[spc1].ls&&!tr[spc1].rs)
     98     {
     99         tr[spc1].val.vl+=tr[spc2].val.vl;
    100         return ;
    101     }
    102     merge(tr[spc1].ls,tr[spc2].ls);
    103     merge(tr[spc1].rs,tr[spc2].rs);
    104     pushup(spc1);
    105     return ;
    106 }
    107 int_2 query(int l,int r,int ll,int rr,int spc)
    108 {
    109     if(!spc||l>rr||ll>r)
    110         return imt;
    111     if(ll<=l&&r<=rr)
    112         return tr[spc].val;
    113     int mid=(l+r)>>1;
    114     return max(query(l,mid,ll,rr,tr[spc].ls),query(mid+1,r,ll,rr,tr[spc].rs));
    115 }
    116 void Insert(int c)
    117 {
    118     int nwp,nwq,lsp,lsq;
    119     nwp=++siz;
    120     s[nwp].len=s[fin].len+1;
    121     for(lsp=fin;lsp&&!s[lsp].tranc[c];lsp=s[lsp].pre)
    122         s[lsp].tranc[c]=nwp;
    123     if(!lsp)
    124         s[nwp].pre=1;
    125     else{
    126         lsq=s[lsp].tranc[c];
    127         if(s[lsq].len==s[lsp].len+1)
    128             s[nwp].pre=lsq;
    129         else{
    130             nwq=++siz;
    131             s[nwq]=s[lsq];
    132             s[nwq].len=s[lsp].len+1;
    133             s[nwp].pre=s[lsq].pre=nwq;
    134             while(s[lsp].tranc[c]==lsq)
    135             {
    136                 s[lsp].tranc[c]=nwq;
    137                 lsp=s[lsp].pre;
    138             }
    139         }
    140     }
    141     fin=nwp;
    142     return ;
    143 }
    144 void Dfs(int x)
    145 {
    146     for(int i=p[x].hd;i;i=e[i].lst)
    147     {
    148         int to=e[i].twd;
    149         Dfs(to);
    150         merge(p[x].rt,p[to].rt);
    151     }
    152     for(int i=0;i<p[x].posquery.size();i++)
    153     {
    154         int h=p[x].posquery[i];
    155         q[h].ans=query(1,m,q[h].l,q[h].r,p[x].rt);
    156     }
    157     return ;
    158 }
    159 int main()
    160 {
    161     scanf("%s",str+1);
    162     n=strlen(str+1);
    163     scanf("%d",&m);
    164     siz=1;
    165     for(int i=1;i<=m;i++)
    166     {
    167         fin=1;
    168         scanf("%s",tmp+1);
    169         int tml=strlen(tmp+1);
    170         for(int j=1;j<=tml;j++)
    171         {
    172             Insert(tmp[j]-'a');
    173             update(1,m,p[fin].rt,i);
    174         }
    175     }
    176     for(int i=2;i<=siz;i++)
    177         ade(s[i].pre,i);
    178     for(int i=1;i<=siz;i++)
    179     {
    180         p[i].fa[0]=s[i].pre;
    181     }
    182     for(int j=1;j<=23;j++){
    183         for(int i=1;i<=siz;i++)
    184         {
    185             p[i].fa[j]=p[p[i].fa[j-1]].fa[j-1];
    186             
    187         }
    188     }
    189     scanf("%d",&Q);
    190     for(int i=1;i<=Q;i++)
    191     {
    192         q[i].Insert();
    193         lpnt[q[i].pr].push_back(i);
    194     }
    195     int root=1;
    196     int lth=0;
    197     for(int i=1;i<=n;i++)
    198     {
    199         int c=str[i]-'a';
    200         while(root&&!s[root].tranc[c])
    201         {
    202             root=s[root].pre;
    203             lth=s[root].len;
    204         }
    205         if(!root)
    206         {
    207             root=1;
    208             lth=0;
    209             continue;
    210         }
    211         root=s[root].tranc[c];
    212         lth++;
    213         for(int j=0;j<lpnt[i].size();j++)
    214         {
    215             int h=lpnt[i][j];
    216             int o=root;
    217             if(lth<q[h].lt)
    218                 continue;
    219             for(int k=23;k>=0;k--)
    220             {
    221                 int nxt=p[o].fa[k];
    222                 if(s[nxt].len>=q[h].lt)
    223                     o=nxt;
    224             }
    225             p[o].posquery.push_back(h);
    226             q[h].pos=o;
    227         }
    228     }
    229     Dfs(1);
    230     for(int i=1;i<=Q;i++)
    231     {
    232         if(q[i].ans.vl==0)
    233             q[i].ans.ps=q[i].l;
    234         printf("%d %d
    ",q[i].ans.ps,q[i].ans.vl);
    235     }
    236     return 0;
    237 }
  • 相关阅读:
    关于ListView
    Camera2
    线程池
    运输层
    计算机网络体系结构
    USACO 2016 US Open Contest Gold T2: Closing the Farm
    USACO 2016 US Open Contest Gold T1: Splitting the Field
    USACO 2016 February Contest Gold T3: Fenced In
    USACO 2016 February Contest Gold T2: Circular Barn Revisited
    USACO 2016 February Contest Gold: T1 Circular Barn
  • 原文地址:https://www.cnblogs.com/blog-Dr-J/p/10085039.html
Copyright © 2020-2023  润新知