konchin_shih

Untitled

Oct 17th, 2022
713
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.33 KB | None | 0 0
  1. #define _CRT_SECURE_NO_WARNINGS
  2. #include<stdio.h>
  3. #include<string.h>
  4. #include<stdlib.h>
  5. #include<stdbool.h>
  6. #include<ctype.h>
  7. typedef long long ll;
  8. #define MAXL 10000000
  9. #define MAXK 20
  10. #define MAXC 128
  11. typedef struct Node{
  12.     int cnt,i;
  13.     struct Node *go[MAXC], *fail, *dic;
  14. }node;
  15. node pool[1<<20],*root;
  16. int nMem,n_pattern;
  17. node* new_Node(){
  18.     pool[nMem].cnt=pool[nMem].i=0;
  19.     pool[nMem].fail=pool[nMem].dic=NULL;
  20.     memset(pool[nMem].go,0,sizeof(pool[nMem].go));
  21.     return &pool[nMem++];
  22. }
  23. void insert(node *cur, const char* str, int pos){
  24.     for(int i=pos;str[i]!='\0';i++){
  25.         int x=!isalnum(str[i])&&str[i]!='\''?' ':(str[i]);
  26.         if(!cur->go[x]) cur->go[x] = new_Node();
  27.         cur=cur->go[x];
  28.     }
  29.     cur->cnt++; cur->i=n_pattern++;
  30. }
  31. void add(const char* str) {insert(root,str,0);}
  32. void make_fail(){
  33.     static node* que[MAXL];
  34.     int qback=0,qfront=0;
  35.     que[qback++]=root;
  36.     while (qback-qfront>0){
  37.         node* fr=que[qfront++];
  38.         for (int i=0; i<MAXC; i++) if (fr->go[i]){
  39.             node *ptr = fr->fail;
  40.             while (ptr && !ptr->go[i]) ptr = ptr->fail;
  41.             fr->go[i]->fail=ptr=(ptr?ptr->go[i]:root);
  42.             fr->go[i]->dic=(ptr->cnt?ptr:ptr->dic);
  43.             que[qback++]=fr->go[i];
  44.         }
  45.     }
  46. }
  47. struct Ans{int a,b;} ans[MAXL];
  48. void swap(struct Ans* a,struct Ans* b){
  49.     static struct Ans tmp;
  50.     tmp=*a,*a=*b,*b=tmp;
  51. }
  52. int query(char* s){ // {pattern, position}
  53.     int ret=0;
  54.     node *cur=root;
  55.     for(int i=0;s[i]!='\0';i++){
  56.         int x=!isalnum(s[i])&&s[i]!='\''?' ':(s[i]);
  57.         while(cur&&!cur->go[x]) cur=cur->fail;
  58.         cur=(cur?cur->go[x]:root);
  59.         if(cur->i>=0) ans[ret].a=cur->i,ans[ret].b=i,ret++;
  60.         for(node *tmp=cur->dic;tmp;tmp=tmp->dic)
  61.             ans[ret].a=tmp->i,ans[ret].b=i,ret++;
  62.     }
  63.     return ret;
  64. }
  65. static inline void init(){
  66.     nMem=0;root=new_Node();n_pattern=0;add("");
  67. }
  68. char str[MAXL]={[0]=' '};
  69. int nsize[MAXK];
  70. bool _charset[MAXC+1]={[EOF+1]=true,['\0'+1]=true},*charset=&_charset[1];
  71. bool cmp(struct Ans a,struct Ans b){
  72.     return a.b<b.b||(a.b==b.b&&nsize[a.a]>nsize[b.a]);
  73. }
  74. void merge_sort(int l,int r){
  75.     if(r-l<=1) return;
  76.     int m=(l+r)>>1;
  77.     merge_sort(l,m),merge_sort(m,r);
  78.     static struct Ans tmp[MAXL];
  79.     for(int i=l;i<r;i++) tmp[i]=ans[i];
  80.     int lptr=l,rptr=m;
  81.     while(lptr<m&&rptr<r)
  82.         if(cmp(tmp[lptr],tmp[rptr]))
  83.             ans[l++]=tmp[lptr++];
  84.         else
  85.             ans[l++]=tmp[rptr++];
  86.     while(lptr<m) ans[l++]=tmp[lptr++];
  87.     while(rptr<r) ans[l++]=tmp[rptr++];
  88. }
  89. static inline void solve(){
  90.     int k;scanf(" %d ",&k);
  91.     for(int i=1;i<=k;i++){
  92.         fgets(str+1,MAXL,stdin);
  93.         nsize[i]=strlen(str+1)-1;
  94.         str[nsize[i]+1]=' ',str[nsize[i]+2]='\0',add(str);
  95.     }
  96.     make_fail();
  97.  
  98.     FILE* fin=fopen("input.txt","r");
  99.     fseek(fin,0,SEEK_END);
  100.     int inSize=ftell(fin);
  101.     rewind(fin);
  102.     str[0]=' ';
  103.     fread(str+1,sizeof(char),inSize,fin),fclose(fin);
  104.  
  105.     int res=query(str);
  106.     for(int i=0;i<res;i++){
  107.         while(i<res&&!ans[i].a) swap(&ans[i],&ans[--res]);
  108.         if(i<res) ans[i].b-=nsize[ans[i].a];
  109.     }
  110.     merge_sort(0,res);
  111.  
  112.     FILE* fout=fopen("output.txt","w");
  113.     for(int i=1,j=0;i<inSize-1;i++){
  114.         while(j<res&&ans[j].b<i) j++;
  115.         if(j<res&&ans[j].b==i)
  116.             fputs("***",fout),i+=nsize[ans[j].a]-1;
  117.         else if(!charset[(int)str[i]])
  118.             fputc(str[i],fout);
  119.     }
  120.     fclose(fout);
  121. }
  122. int main(){
  123.     init();
  124.     solve();
  125.     return 0;
  126. }
Advertisement
Add Comment
Please, Sign In to add comment