这题主要就是解码过程很恶心,不能用char存,一共wa了20发
题意:先给n串加密后的字符,然后m串加密后的字符,解码之后求n对应每个m的匹配数,很显然的ac自动机
加密过程是先用对应ascii表的标号来代替字符,然后把这些数字转换成8位的二进制,全部连起来,然后每6位算一个数,用二进制算成整数,最后用这些整数来映射给定的表
题解:反解密就好了,要注意细节,很容易Segmentation Fault,最后算出来的字符用int存,然后跑ac自动机就行了
#include<bits/stdc++.h> #define fi first #define se second #define mp make_pair #define pb push_back #define pii pair<int,int> #define C 0.5772156649 #define pi acos(-1.0) #define ll long long #define mod 1000000007 #define ls l,m,rt<<1 #define rs m+1,r,rt<<1|1using namespace std;const double g=10.0,eps=1e-7; const int N=520*64+10,maxn=60000+10,inf=0x3f3f3f;inline void debug(){cout<<"fuck"<<endl;}char s[4000]; int de[4000],sz; int digit[4000*6]; struct Trie{int tot,root;int Next[N][256],fail[N],End[N];int newnode(){for(int i=0;i<256;i++)Next[tot][i]=-1;End[tot]=0;return tot++;}void init(){tot=0;root=newnode();}void insertstring(int id){int now=root;for(int i=0;i<sz;i++){if(Next[now][de[i]]==-1)Next[now][de[i]]=newnode();now=Next[now][de[i]];}End[now]=id;}void build(){queue<int>q;fail[root]=root;for(int i=0;i<256;i++){if(Next[root][i]==-1)Next[root][i]=root;else{fail[Next[root][i]]=root;q.push(Next[root][i]);}}while(!q.empty()){int now=q.front();q.pop();for(int i=0;i<256;i++){if(Next[now][i]==-1)Next[now][i]=Next[fail[now]][i];else{fail[Next[now][i]]=Next[fail[now]][i];q.push(Next[now][i]);}}}}bool vis[550];int query(int n){int now=root;memset(vis,0,sizeof vis);for(int i=0;i<sz;i++){now=Next[now][de[i]];int te=now;while(te!=root){if(End[te])vis[End[te]]=1;te=fail[te];}}int res=0;for(int i=1;i<=n;i++)if(vis[i])res++;return res;} }; int getnew(char x) {if(x>='A'&&x<='Z')return x-'A';if(x>='a'&&x<='z')return x-'a'+26;if(x>='0'&&x<='9')return x-'0'+52;if(x=='+')return 62;else return 63; } void change(char s[]) {sz=0;int len=strlen(s);while(s[len-1]=='=')len--;vector<int>v;for(int i=0;i<len;i++)v.pb(getnew(s[i]));memset(digit,0,sizeof digit);for(int i=0;i<v.size();i++){for(int j=6*(i+1)-1;j>=6*i;j--){if(v[i]&1)digit[j]=1;v[i]/=2;}}sz=v.size()*6/8;for(int i=0;i<sz;i++){de[i]=0;for(int j=8*i;j<8*(i+1);j++)de[i]=(de[i]<<1)+digit[j];// cout<<de[i]<<" "; }// cout<<endl; } Trie ac; int main() {ios::sync_with_stdio(false);cin.tie(0);int n;while(~scanf("%d",&n)){ac.init();for(int i=1;i<=n;i++){scanf("%s",s);change(s);ac.insertstring(i);}ac.build();int k;scanf("%d",&k);while(k--){scanf("%s",s);change(s);printf("%d\n",ac.query(n));}puts("");}return 0; } /****************************************/