Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #define _CRT_SECURE_NO_WARNINGS
- #include<stdio.h>
- #include<string.h>
- #include<stdlib.h>
- #include<stdbool.h>
- #include<ctype.h>
- typedef long long ll;
- #define MAXL 10000000
- #define MAXK 20
- #define MAXC 128
- typedef struct Node{
- int cnt,i;
- struct Node *go[MAXC], *fail, *dic;
- }node;
- node pool[1<<20],*root;
- int nMem,n_pattern;
- node* new_Node(){
- pool[nMem].cnt=pool[nMem].i=0;
- pool[nMem].fail=pool[nMem].dic=NULL;
- memset(pool[nMem].go,0,sizeof(pool[nMem].go));
- return &pool[nMem++];
- }
- void insert(node *cur, const char* str, int pos){
- for(int i=pos;str[i]!='\0';i++){
- int x=!isalnum(str[i])&&str[i]!='\''?' ':(str[i]);
- if(!cur->go[x]) cur->go[x] = new_Node();
- cur=cur->go[x];
- }
- cur->cnt++; cur->i=n_pattern++;
- }
- void add(const char* str) {insert(root,str,0);}
- void make_fail(){
- static node* que[MAXL];
- int qback=0,qfront=0;
- que[qback++]=root;
- while (qback-qfront>0){
- node* fr=que[qfront++];
- for (int i=0; i<MAXC; i++) if (fr->go[i]){
- node *ptr = fr->fail;
- while (ptr && !ptr->go[i]) ptr = ptr->fail;
- fr->go[i]->fail=ptr=(ptr?ptr->go[i]:root);
- fr->go[i]->dic=(ptr->cnt?ptr:ptr->dic);
- que[qback++]=fr->go[i];
- }
- }
- }
- struct Ans{int a,b;} ans[MAXL];
- void swap(struct Ans* a,struct Ans* b){
- static struct Ans tmp;
- tmp=*a,*a=*b,*b=tmp;
- }
- int query(char* s){ // {pattern, position}
- int ret=0;
- node *cur=root;
- for(int i=0;s[i]!='\0';i++){
- int x=!isalnum(s[i])&&s[i]!='\''?' ':(s[i]);
- while(cur&&!cur->go[x]) cur=cur->fail;
- cur=(cur?cur->go[x]:root);
- if(cur->i>=0) ans[ret].a=cur->i,ans[ret].b=i,ret++;
- for(node *tmp=cur->dic;tmp;tmp=tmp->dic)
- ans[ret].a=tmp->i,ans[ret].b=i,ret++;
- }
- return ret;
- }
- static inline void init(){
- nMem=0;root=new_Node();n_pattern=0;add("");
- }
- char str[MAXL]={[0]=' '};
- int nsize[MAXK];
- bool _charset[MAXC+1]={[EOF+1]=true,['\0'+1]=true},*charset=&_charset[1];
- bool cmp(struct Ans a,struct Ans b){
- return a.b<b.b||(a.b==b.b&&nsize[a.a]>nsize[b.a]);
- }
- void merge_sort(int l,int r){
- if(r-l<=1) return;
- int m=(l+r)>>1;
- merge_sort(l,m),merge_sort(m,r);
- static struct Ans tmp[MAXL];
- for(int i=l;i<r;i++) tmp[i]=ans[i];
- int lptr=l,rptr=m;
- while(lptr<m&&rptr<r)
- if(cmp(tmp[lptr],tmp[rptr]))
- ans[l++]=tmp[lptr++];
- else
- ans[l++]=tmp[rptr++];
- while(lptr<m) ans[l++]=tmp[lptr++];
- while(rptr<r) ans[l++]=tmp[rptr++];
- }
- static inline void solve(){
- int k;scanf(" %d ",&k);
- for(int i=1;i<=k;i++){
- fgets(str+1,MAXL,stdin);
- nsize[i]=strlen(str+1)-1;
- str[nsize[i]+1]=' ',str[nsize[i]+2]='\0',add(str);
- }
- make_fail();
- FILE* fin=fopen("input.txt","r");
- fseek(fin,0,SEEK_END);
- int inSize=ftell(fin);
- rewind(fin);
- str[0]=' ';
- fread(str+1,sizeof(char),inSize,fin),fclose(fin);
- int res=query(str);
- for(int i=0;i<res;i++){
- while(i<res&&!ans[i].a) swap(&ans[i],&ans[--res]);
- if(i<res) ans[i].b-=nsize[ans[i].a];
- }
- merge_sort(0,res);
- FILE* fout=fopen("output.txt","w");
- for(int i=1,j=0;i<inSize-1;i++){
- while(j<res&&ans[j].b<i) j++;
- if(j<res&&ans[j].b==i)
- fputs("***",fout),i+=nsize[ans[j].a]-1;
- else if(!charset[(int)str[i]])
- fputc(str[i],fout);
- }
- fclose(fout);
- }
- int main(){
- init();
- solve();
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment