• HDU5069(AC自动机+线段树)


    题意:http://acm.hdu.edu.cn/showproblem.php?pid=5069

    给你n个串,m个询问:以b串的前缀和a串的后缀最长是多少。

    思路:https://blog.csdn.net/gatevin/article/details/46123703

    讲的很全面了。

      1 #define IOS ios_base::sync_with_stdio(0); cin.tie(0);
      2 #include <cstdio>//sprintf islower isupper
      3 #include <cstdlib>//malloc  exit strcat itoa system("cls")
      4 #include <iostream>//pair
      5 #include <fstream>//freopen("C:\Users\13606\Desktop\Input.txt","r",stdin);
      6 #include <bitset>
      7 //#include <map>
      8 //#include<unordered_map>
      9 #include <vector>
     10 #include <stack>
     11 #include <set>
     12 #include <string.h>//strstr substr strcat
     13 #include <string>
     14 #include <time.h>// srand(((unsigned)time(NULL))); Seed n=rand()%10 - 0~9;
     15 #include <cmath>
     16 #include <deque>
     17 #include <queue>//priority_queue<int, vector<int>, greater<int> > q;//less
     18 #include <vector>//emplace_back
     19 //#include <math.h>
     20 #include <cassert>
     21 #include <iomanip>
     22 //#include <windows.h>//reverse(a,a+len);// ~ ! ~ ! floor
     23 #include <algorithm>//sort + unique : sz=unique(b+1,b+n+1)-(b+1);+nth_element(first, nth, last, compare)
     24 using namespace std;//next_permutation(a+1,a+1+n);//prev_permutation
     25 //******************
     26 clock_t __START,__END;
     27 double __TOTALTIME;
     28 void _MS(){__START=clock();}
     29 void _ME(){__END=clock();__TOTALTIME=(double)(__END-__START)/CLOCKS_PER_SEC;cout<<"Time: "<<__TOTALTIME<<" s"<<endl;}
     30 //***********************
     31 #define rint register int
     32 #define fo(a,b,c) for(rint a=b;a<=c;++a)
     33 #define fr(a,b,c) for(rint a=b;a>=c;--a)
     34 #define mem(a,b) memset(a,b,sizeof(a))
     35 #define pr printf
     36 #define sc scanf
     37 #define ls rt<<1
     38 #define rs rt<<1|1
     39 typedef pair<int,int> PII;
     40 typedef vector<int> VI;
     41 typedef unsigned long long ull;
     42 typedef long long ll;
     43 typedef double db;
     44 const db E=2.718281828;
     45 const db PI=acos(-1.0);
     46 const ll INF=(1LL<<60);
     47 const int inf=(1<<30);
     48 const db ESP=1e-9;
     49 const int mod=(int)1e9+7;
     50 const int N=(int)2e5+10;
     51 
     52 char s[N];
     53 int in_id[N];
     54 struct node
     55 {
     56     int l,r;
     57 }P[N];
     58 
     59 ll max_[N<<2],add[N<<2];
     60 
     61 void up(int rt,int l,int r){
     62     max_[rt]=max(max_[ls],max_[rs]);
     63 }
     64 void dn(int rt){
     65     if(add[rt]!=0)
     66     {
     67         max_[ls]=max(max_[ls],add[rt]);
     68         max_[rs]=max(max_[rs],add[rt]);
     69         add[ls]=max(add[ls],add[rt]);
     70         add[rs]=max(add[rs],add[rt]);
     71         add[rt]=0;
     72     }
     73 }
     74 void Build(int l,int r,int rt)
     75 {
     76     max_[rt]=0;
     77     add[rt]=0;
     78     if(l==r)
     79     {
     80         return;
     81     }
     82     int mid=(l+r)>>1;
     83 
     84     Build(l,mid,rt<<1);
     85     Build(mid+1,r,rt<<1|1);
     86     up(rt,l,r);
     87 }
     88 ll query_dot(int pos,int l,int r,int rt)
     89 {
     90     if(l==r)
     91     {
     92         return max_[rt];
     93     }
     94 
     95     int mid=(l+r)>>1;
     96     dn(rt);
     97     if(pos<=mid)
     98         return query_dot(pos,l,mid,rt<<1);
     99     else
    100         return query_dot(pos,mid+1,r,rt<<1|1);
    101 }
    102 void update_qu(int L,int R,ll V,int l,int r,int rt)
    103 {
    104     if(L>R)return;
    105     if(L<=l&&r<=R)
    106     {
    107         max_[rt]=max(max_[rt],V);
    108         add[rt]=max(add[rt],V);
    109         return;
    110     }
    111 
    112     int mid=(l+r)>>1;
    113     dn(rt);
    114     if(L<=mid)
    115         update_qu(L,R,V,l,mid,rt<<1);
    116     if(R>mid)
    117         update_qu(L,R,V,mid+1,r,rt<<1|1);
    118     up(rt,l,r);
    119 }
    120 //-----------------------线段树
    121 //====================================================================
    122 class MAP
    123 {
    124 public:
    125     struct EDGE
    126     {
    127         int to,next;
    128     }edge[N];
    129 
    130     int tot;
    131     int head[N];
    132 
    133     int dfn[N],DFN,SZ[N];
    134     void Init(int n)
    135     {
    136         tot=DFN=0;
    137         for(int i=0;i<=n;++i)
    138             head[i]=SZ[i]=dfn[i]=0;
    139     }
    140     void add(int from,int to)
    141     {
    142         ++tot;
    143         edge[tot].to=to;
    144         edge[tot].next=head[from];
    145         head[from]=tot;
    146     }
    147     int dfs(int u,int fa)
    148     {
    149         dfn[u]=++DFN;
    150         SZ[dfn[u]]=1;
    151         for(int i=head[u];i;i=edge[i].next)
    152         {
    153             int to=edge[i].to;
    154             if(to!=fa)
    155                 SZ[dfn[u]]+=dfs(to,u);
    156         }
    157         return SZ[dfn[u]];
    158     }
    159 }mp;
    160 //====================================================================
    161 //------------------------AC
    162 class ac_automaton//失配时,尽可能长得保留后缀以重新开始匹配.
    163 {
    164 public:
    165     int tot;
    166     int trie[N][27];
    167     int fail[N];
    168     //other
    169     //--------------
    170     void Init(int n)
    171     {
    172         tot=0;
    173         for(int i=0;i<=n;++i)
    174         {
    175             fail[i]=0;
    176             for(int j=1;j<=26;++j)
    177                 trie[i][j]=0;
    178         }
    179     }
    180     int Insert(int l,int r)
    181     {
    182         int rt=0;
    183         for(int i=l;i<=r;++i)
    184         {
    185             int id=s[i]-'A'+1;
    186             if(!trie[rt][id])trie[rt][id]=++tot;
    187             rt=trie[rt][id];
    188         }
    189         return rt;
    190     }
    191     void Getfail()
    192     {
    193         queue<int>q;
    194         for(int i=1;i<=26;++i)
    195         {
    196             int id=trie[0][i];
    197             if(id)
    198             {
    199                 fail[id]=0;
    200                 q.push(id);
    201             }
    202         }
    203         while(!q.empty())
    204         {
    205             int rt=q.front();q.pop();
    206             for(int i=1;i<=26;++i)
    207             {
    208                 int id=trie[rt][i];
    209                 if(id)
    210                 {
    211                     fail[id]=trie[fail[rt]][i];
    212                     q.push(id);
    213                 }
    214                 else
    215                     trie[rt][i]=trie[fail[rt]][i];
    216             }
    217         }
    218     }
    219     void Find(int l,int r,ll sgm)
    220     {
    221         int rt=0;
    222         for(int i=l;i<=r;++i)
    223         {
    224             rt=trie[rt][s[i]-'A'+1];
    225             int pos=mp.dfn[rt];
    226             update_qu(pos,pos+mp.SZ[pos]-1,i-l+1+sgm,1,tot+1,1);
    227         //    for(int j=1;j<=tot+1;++j)check(j,1,tot+1,1);
    228         //    cout<<endl;
    229         }
    230     }
    231 }AC;
    232 
    233 struct GG
    234 {
    235     int id,to_a;
    236 };
    237 vector<vector<GG> >G(N);
    238 ll ans[N];
    239 int aa[N],bb[N];
    240 
    241 int main()
    242 {
    243 //    freopen("C:\Users\13606\Desktop\Input.txt","r",stdin);
    244 //    freopen("C:\Users\13606\Desktop\1.txt","w",stdout);
    245     int n,m;
    246     while(~sc("%d%d",&n,&m))
    247     {
    248         for(int i=1;i<=n;++i)G[i].clear();
    249         int len=0;
    250         for(int i=1;i<=n;++i)
    251         {
    252             sc("%s",s+1+len);
    253             P[i].l=1+len;
    254             len+=strlen(s+1+len);
    255             P[i].r=len;
    256         }
    257         AC.Init(len);
    258         for(int i=1;i<=n;++i)
    259             in_id[i]=AC.Insert(P[i].l,P[i].r);
    260         AC.Getfail();
    261         int tot=AC.tot+1;
    262         Build(1,tot,1);
    263 
    264         for(int i=1;i<=m;++i)
    265         {
    266             int a,b;
    267             sc("%d%d",&a,&b);
    268             aa[i]=a,bb[i]=b;
    269             G[b].push_back({i,a});
    270         }
    271         mp.Init(tot);
    272         for(int i=1;i<=AC.tot;i++)
    273         {
    274             mp.add(i,AC.fail[i]);
    275             mp.add(AC.fail[i],i);
    276         }
    277         mp.dfs(0,-1);
    278         ll sgm=-100000000;
    279         for(int i=1;i<=n;++i)
    280         {
    281             sgm+=100000000;
    282             AC.Find(P[i].l,P[i].r,sgm);
    283             int sz=G[i].size();
    284             for(int j=0;j<sz;++j)
    285             {
    286                 GG now=G[i][j];
    287                 ans[now.id]=max(0LL,query_dot(mp.dfn[in_id[now.to_a]],1,tot,1)-sgm);
    288             }
    289         }
    290         for(int i=1;i<=m;++i)
    291             pr("%lld
    ",ans[i]);
    292     }
    293     return 0;
    294 }
    295 
    296 /**************************************************************************************/
  • 相关阅读:
    IDEA常用快捷键和设置
    java反射总结
    IO编程总结
    3月份主要学习
    idea中maven将jar包导入本地maven库
    hive常用命令
    CentOS7 安装图形化桌面
    vue+leaflet
    Springboot + Rabbitmq + WebSocet + vue
    VUE 中引入百度地图(vue-Baidu-Map)
  • 原文地址:https://www.cnblogs.com/--HPY-7m/p/12263793.html
Copyright © 2020-2023  润新知