ZOJ 2619 && HDU 3058
2013-05-02 11:27
267 查看
两道AC自动机+高消的求期望问题
先说HDU 3058
ZOJ 2619
具体数学上的结论题
高消的做法(注意这里所有的变量都是整数,用long long的高消,用doube卡死精度)
先说HDU 3058
#include <cstdio> #include <cstring> #include <cmath> #include <queue> #include <algorithm> #define N 110 using namespace std; int next [8],flag ,fail ,pos,tot,id ; int n; char s[11]; double mat[110][110]; int newnode(){ memset(next[pos],0,sizeof(next[pos])); flag[pos]=fail[pos]=0; return pos++; } void insert(){ int p=0,i; for(i=0;s[i];i++){ int k=s[i]-'A'; p=next[p][k]?next[p][k]:next[p][k]=newnode(); } flag[p]=1; } void makefail(){ queue<int>q; q.push(0); while(!q.empty()){ int u=q.front(); q.pop(); for(int i=0;i<n;i++){ int v=next[u][i]; if(v==0) next[u][i]=next[fail[u]][i]; else q.push(v); if(u && v){ fail[v]=next[fail[u]][i]; flag[v]|=flag[fail[v]]; } } } } void make_mat(){ int i,j; tot=0; memset(id,0,sizeof(id)); for(i=0;i<pos;i++) if(flag[i]==0) id[i]=tot++; memset(mat,0,sizeof(mat)); for(i=0;i<pos;i++){ if(flag[i]==1)continue; mat[id[i]][tot]=-n; mat[id[i]][id[i]]=-n; for(j=0;j<n;j++){ int k=next[i][j]; if(flag[k]==1)continue; mat[id[i]][id[k]]+=1.0; } } } bool gauss(){ int i,j,row,id; double maxx; for(row=0;row<tot;row++){ maxx=fabs(mat[row][row]);id=row; for(i=row+1;i<tot;i++) if(fabs(mat[i][row]>maxx)){ maxx=fabs(mat[i][row]); id=i; } if(maxx<1e-11) return 0; //我一开始这里精度设置1e-8就WA死了。。。。。。 if(id!=row){ for(j=0;j<=tot;j++) swap(mat[row][j],mat[id][j]); } for(i=row+1;i<tot;i++){ for(j=tot;j>=row;j--) mat[i][j]-=mat[i][row]/mat[row][row]*mat[row][j]; } } for(i=tot-1;i>=0;i--){ for(j=i+1;j<tot;j++) mat[i][tot]-=mat[i][j]*mat[j][j]; mat[i][i]=mat[i][tot]/mat[i][i]; } return 1; } int main(){ int t,T,m,i; scanf("%d",&T); for(t=1;t<=T;t++){ scanf("%d %d",&n,&m); pos=0,newnode(); for(i=1;i<=m;i++){ scanf("%s",s); insert(); } makefail(); make_mat(); gauss(); printf("%.2lf\n",mat[0][0]); } }
ZOJ 2619
具体数学上的结论题
#include <cstdio> #include <cstring> typedef long long ll; using namespace std; char s[410]; bool judge(int s1,int s2){ while(s[s1] && s[s2]){ if(s[s1]!=s[s2]) return 0; s1++,s2++; } return 1; } int main(){ int t,T; int n,i; ll ans; scanf("%d",&T); for(t=1;t<=T;t++){ scanf("%d %s",&n,s); ans=0; for(i=0;s[i];i++){ if(judge(0,i)) ans++; ans*=n; } printf("Case %d:\n",t); printf("%lld\n",ans); if(t!=T)puts(""); } }
高消的做法(注意这里所有的变量都是整数,用long long的高消,用doube卡死精度)
#include <cstdio> #include <cstring> #include <cmath> #include <queue> #include <algorithm> #define N 110 typedef long long ll; using namespace std; int next [26],flag ,fail ,pos,tot,id ; int n; char s[21]; ll mat[110][110]; int newnode(){ memset(next[pos],0,sizeof(next[pos])); flag[pos]=fail[pos]=0; return pos++; } void insert(){ int p=0,i; for(i=0;s[i];i++){ int k=s[i]-'A'; p=next[p][k]?next[p][k]:next[p][k]=newnode(); } flag[p]=1; } void makefail(){ queue<int>q; q.push(0); while(!q.empty()){ int u=q.front(); q.pop(); for(int i=0;i<n;i++){ int v=next[u][i]; if(v==0) next[u][i]=next[fail[u]][i]; else q.push(v); if(u && v){ fail[v]=next[fail[u]][i]; flag[v]|=flag[fail[v]]; } } } } void make_mat(){ int i,j; tot=0; memset(id,0,sizeof(id)); for(i=0;i<pos;i++) if(flag[i]==0) id[i]=tot++; memset(mat,0,sizeof(mat)); for(i=0;i<pos;i++){ if(flag[i]==1)continue; mat[id[i]][tot]=-n; mat[id[i]][id[i]]=-n; for(j=0;j<n;j++){ int k=next[i][j]; if(flag[k]==1)continue; mat[id[i]][id[k]]+=1; } } /*printf("%d\n",tot); printf("Matrix has %d rows and %d columns\n",tot,tot+1); for(i=0;i<tot;i++){ for(j=0;j<=tot;j++) printf("%lld\t",mat[i][j]); puts(""); } puts("*******");*/ } ll gcd(ll a,ll b){ if (b==0) return a; else return gcd(b,a%b); } bool gauss(){ int i,j,row,id; ll maxx; for(row=0;row<tot;row++){ maxx=abs(mat[row][row]),id=row; //这里要挑一个小的移动,如果还是大的后面会溢出 或者干脆不移动也可以 for(i=row+1;i<tot;i++) if(abs(mat[i][row]<maxx) && mat[i][row]){ maxx=abs(mat[i][row]); id=i; } //if(maxx==0)continue; if(id!=row){ for(j=0;j<=tot;j++) swap(mat[row][j],mat[id][j]); } for(i=row+1;i<tot;i++){ if(mat[i][row]!=0){ ll q=gcd(mat[i][row],mat[row][row]); ll gb=mat[i][row]*mat[row][row]/q; ll l1,l2; l1=gb/mat[i][row]; l2=gb/mat[row][row]; for(j=row;j<=tot;j++) mat[i][j]=mat[i][j]*l1-mat[row][j]*l2; } } /*for(i=0;i<tot;i++){ for(j=0;j<=tot;j++) printf("%lld\t",mat[i][j]); puts(""); } puts("*******");*/ } for(i=tot-1;i>=0;i--){ for(j=i+1;j<tot;j++) mat[i][tot]-=mat[i][j]*mat[j][j]; mat[i][i]=mat[i][tot]/mat[i][i]; } return 1; } int main(){ int t,T,m,i; //freopen("a.txt","r",stdin); //freopen("b.txt","w",stdout); scanf("%d",&T); for(t=1;t<=T;t++){ scanf("%d",&n); pos=0,newnode(); scanf("%s",s); insert(); makefail(); make_mat(); gauss(); printf("Case %d:\n",t); printf("%lld\n",mat[0][0]); if(t!=T) puts(""); } }
相关文章推荐
- HDU 4791 & ZOJ 3726 Alice's Print Service (数学 打表)
- TOJ 4373 HDU 4430 ZOJ 3665 Yukari's Birthday / 二分
- POJ1546 & HDU 1335 & ZOJ 1334 Basically Speaking(进制转换)
- HDU 4791 & ZOJ 3726 Alice's Print Service (数学 打表)
- HDU 1423 && ZOJ 2432 (LCIS模板)
- HDU 2377 && ZOJ 2412
- HDU 1021/ZOJ 2060 Fibonacci Again(数论&整除推导&位运算技巧)
- Codeforces 136 divIID && zoj 3633 && HDU 4358
- HDU 1242 && ZOJ 1649( BFS (队列 || 优先队列)).
- HDU 1365 & ZOJ 1456 Minimum Transport Cost(记录路径Floyd)
- UVa 442/HDU 1082/ZOJ 1094 Matrix Chain Multiplication(模拟&栈)
- zoj 1002 && hdu 1045 Fire Net
- hdu 4424 & zoj 3659 Conquer a New Region (并查集 + 贪心)
- zoj 1149 && hdu 1059 && poj 1014 Dividing
- POJ 1071 & HDU 1364 & ZOJ 1019 Illusive Chase(DFS)
- zoj 2511 & hdu 1031 Design T-Shirt
- ZOJ 1108 & HDU 1160 - FatMouse's Speed
- hdu 4071& poj 3873 & zoj 3386 & uva 12197 Trick or Treat 三分法
- POJ 2777 && ZOJ 1610 &&HDU 1698 --线段树--区间更新
- POJ 3654 & ZOJ 2936 & HDU 2723 Electronic Document Security(模拟)