hdu 5164 Matching on Array (奇葩版ac自动机)
来源:互联网 发布:淘宝卖化妆品 编辑:程序博客网 时间:2024/05/22 07:55
题意:
给出一个a序列,m个b序列,a能通过倍数关系能出现多少b串。例如a{ 2 4 8 } b{ 1 2 } 那么a中的{ 2 4 } 和{ 4 8 } 是可以通过b序列通过倍数变成的。
题解:
我们可以把串进行缩放,然后缩放后的串进行匹配。
对于m==1的情况用kmp 其他情况用ac自动机。搞一个分数类进行处理。自动机的边用map,对奇葩的地方就是这里,用map做边,map<Node,int>next[SIZE] 这样就通过map映射Node类型(分数类)来解决节点的存储关系。弄完这个,就是无脑的自动机匹配。可惜哥弄了一个晚上的代码最终以wa结尾。。。找啊找,各种原因,最终发现可能是cnt初始化为0的缘故,因为我的代码写法,会导致冲突!应为map如果不存对应的边,那么会返回0,同样根编号也是0,这样很明显冲突啊,所以各种wa!!!最后参照了别人的代码解决了这个问题。由于g++类无法存太大的数组,因此没写成类的形式。这题好题啊,出题人脑洞太大了,ORZ!
#include<iostream>#include<math.h>#include<stdio.h>#include<algorithm>#include<string.h>#include<vector>#include<queue>#include<map>#include<set>using namespace std;#define B(x) (1<<(x))typedef __int64 ll;const int oo=0x3f3f3f3f;const ll OO=1LL<<61;const int MOD=10007;const int maxn=110000;const int maxm=1000005;const int SIZE=1000005;int Next[maxm];//const int type=4;inline int gcd(int a,int b){ return b==0 ? a : gcd(b,a%b);}struct Node{ int up,down; Node(){} Node(int a,int b){ up=a;down=b; int temp; if(up>down)temp=gcd(up,down); else temp=gcd(down,up); up/=temp; down/=temp; } bool operator==(const Node& a)const{ return up==a.up&&down==a.down; } bool operator!=(const Node& a)const{ return up!=a.up||down!=a.down; } bool operator<(const Node& a)const{ if(up!=a.up) return up<a.up; return down<a.down; }}a[maxn],b[maxn];void input(Node buff[],int len){ int x,y; scanf("%d",&x); for(int i=1;i<len;i++){ scanf("%d",&y); buff[i]=Node(y,x); x=y; }}map<Node,int>next[SIZE];int fail[SIZE],flag[SIZE];int cnt,root;int newNode(){ next[cnt].clear(); flag[cnt++]=0; return cnt-1;}void Init(){ cnt=1; root=newNode();}void Insert(Node buff[],int len){ int now=root; Node k; for(int i=1;i<=len;i++){ k=buff[i]; if(next[now][k]==0) next[now][k]=newNode(); now=next[now][k]; }//for flag[now]++;}void build(){ fail[root]=0; Node k; queue<int>Q; ///注:next[now][i] <=> it->second ; i <=>it->first; for(map<Node,int>::iterator it=next[root].begin();it!=next[root].end();++it){ fail[it->second]=root; Q.push(it->second); }//for while(!Q.empty()){ int now=Q.front();Q.pop(); flag[now]+=flag[fail[now]]; for(map<Node,int>::iterator it=next[now].begin();it!=next[now].end();++it){ int temp=fail[now]; int nxt=next[temp][it->first]; while(temp&&!nxt){ temp=fail[temp]; nxt=next[temp][it->first]; } if(temp) fail[it->second]=nxt; else fail[it->second]=root; Q.push(it->second); }//for }//while}ll Search(Node buff[],int len){ int now=root; ll ans=0; for(int i=1;i<=len;i++){ int nxt=next[now][buff[i]]; while(now&&!nxt){ now=fail[now]; nxt=next[now][buff[i]]; } if(now) now=nxt; else now=root; ans+=flag[now]; }//for return ans;}void get_next(Node T[],int len){ int i=0; Next[i]=-1; int j=-1; while(i<len) { if(j==-1||T[i]==T[j]){ i++;j++; Next[i]=j; }else j=Next[j]; }}ll kmp(Node S[],Node T[],int lenS,int lenT){ ll ans=0; int i=0,j=0; while(i<lenS){ if(j==-1||S[i]==T[j]){ i++; j++; }else j=Next[j]; if(j==lenT) ans++; }//for return ans;}int main(){ int T,m,n,k; ll ans; scanf("%d",&T); while(T--){ Init(); scanf("%d %d",&n,&m); input(a,n); ans=0; if(m>1){ for(int i=1;i<=m;i++){ scanf("%d",&k); input(b,k); if(k>1) Insert(b,k-1); else ans+=n; }//for build(); ans+=Search(a,n-1); }else{ scanf("%d",&k); input(b,k); if(k>1){ get_next(b+1,k-1); ans=kmp(a+1,b+1,n-1,k-1); }else ans+=n; }//else printf("%I64d\n",ans); }//while return 0;}//main/**24 12 4 8 162 1 25 32 4 2 4 63 1 2 11 52 16 8*/
0 0
- hdu 5164 Matching on Array (奇葩版ac自动机)
- 【HDU】5164 Matching on Array 【AC自动机】
- hdu 5164 Matching on Array AC自动机
- hdu 5164 Matching on Array (用map实现的ac自动机)
- HDU 5164 Matching on Array AC自动机套map
- 【AC自动机】 HDOJ 5164 Matching on Arrayy
- hdu5164 Matching on Array map实现ac自动机
- HDU--3407[String-Matching Automata] AC自动机或kmp
- HDU 3695:Computer Virus on Planet Pandora(AC自动机裸题,数组实现AC自动机)
- HDU 3695 Computer Virus on Planet Pandora(AC自动机)
- HDU 3695 Computer Virus on Planet Pandora(AC自动机)
- hdu 3695 Computer Virus on Planet Pandora AC自动机
- hdu 3695 Computer Virus on Planet Pandora ac自动机
- HDU 3695 Computer Virus on Planet Pandora (AC自动机)
- HDU 3695 Computer Virus on Planet Pandora AC自动机
- 【AC自动机】HDU 3695 Computer Virus on Planet Pandora 裸题
- hdu 3695 Computer Virus on Planet Pandora(AC自动机)
- HDU 3695 Computer Virus on Planet Pandora (AC自动机)
- 程序员练级攻略----转自酷壳网coolshell.c n
- java の finally
- Tomcat 的三种(bio,nio.apr) 高级 Connector 运行模式
- R语言逐行读取并处理大文件
- 分享:安卓开发者必备的42个链接
- hdu 5164 Matching on Array (奇葩版ac自动机)
- 游戏公司之奇葩——一个真实的故事 像张江一家公司
- Codeforces 521A DNA Alignment 规律
- css第一部分简介
- Android 百度地图开发(一)--- 申请API Key和在项目中显示百度地图
- Servlet入门笔记2
- css第二部分核心原理
- Android 百度地图开发(二)--- 定位功能之MyLocationOverlay,PopupOverlay的使用
- 构造函数与析构函数的原理