【JZOJ5045】【NOI2017模拟4.5】无限棋盘
2017-04-06 09:28
429 查看
Description
无聊的小A在一个无限大的棋盘上玩游戏,这个棋盘由一个M*N的模板不停重复生成。例如,当模板为:honi
hsin
时,我们会生成如下棋盘:
…honihonihonihoni…
…hsinhsinhsinhsin…
…honihonihonihoni…
…hsinhsinhsinhsin…
其中,该棋盘在任意一个方向都可以无限延伸。
现在小A在棋盘上随机挑选一个位置,又随机挑选一个方向(八个方向之一),并从该位置开始,沿着挑选的方向走K-1步,沿路记下每一个经过的字母(包括起点),得到一个长度为K的字符串。他重复并独立地执行该操作两次,得到两个长度为K的字符串,他现在想知道,这两个字符串相同的概率是多大?
Data Constraint
62.5%的数据满足:M=N。Solution
我们发现这k步走的都是一个方向,所以经大佬提醒,我们这k步可以用倍增来做。我们设f[i][j][k][l]表示以(i,j)为起点往l方向走2^k步后的字符串的哈希值。这显然可以用倍增来做。然后我们把所有起点的八方向的走k步后的字符串的哈希值都加入数组。排一下序就可找出所有相同的字符串的数量。与64*(n*m)^2取一下gcd即可。注意:哈希值这种东西可以用unsigned long long 的2^64自然溢出来做。Code
#include<iostream> #include<cmath> #include<cstring> #include<cstdio> #include<algorithm> #define ll long long using namespace std; const ll maxn=500+5,mo=1e9+3; const ll f[8][2]={{0,1},{1,0},{0,-1},{-1,0},{1,1},{-1,1},{1,-1},{-1,-1}}; ll f1[maxn][maxn][30],er[maxn],a[maxn*maxn*8]; char s[maxn]; ll n,m,p,i,t,j,k,l,x,y,z,ans,q,num; ll gcd(ll x,ll y){ ll r=x%y; while (r) x=y,y=r,r=x%y; return y; } int main(){ freopen("chessboard.in","r",stdin);freopen("chessboard.out","w",stdout); scanf("%llu%llu%llu\n",&n,&m,&p); for (i=1;i<=n;i++){ scanf("%s\n",s+1); for (j=1;j<=m;j++){ t=s[j]-97; f1[i][j][0]=t; } } t=log(p)/log(2);er[0]=1; for (i=1;i<=t;i++) er[i]=er[i-1]*2; for (l=0;l<8;l++){z=27; for (k=1;k<=t;k++){ for (i=1;i<=n;i++) for (j=1;j<=m;j++){ x=(i+f[l][0]*er[k-1])%n;y=(j+f[l][1]*er[k-1])%m; x=(x<=0)?x+n:x;y=(y<=0)?y+m:y; f1[i][j][k]=f1[i][j][k-1]*z+f1[x][y][k-1]; } z=z*z; } for (i=1;i<=n;i++) for (j=1;j<=m;j++){ x=i,y=j;q=0;k=27; for (z=0;z<=t;z++){ if (er[z]&p){ q=q*k+f1[x][y][z]; x=(x+f[l][0]*er[z])%n;y=(y+f[l][1]*er[z])%m; x=(x<=0)?x+n:x;y=(y<=0)?y+m:y; } k=k*k; } a[++num]=q; } } sort(a+1,a+num+1);t=0; for (i=1;i<=num;i++) if (a[i]==a[i-1]) t++; else ans+=t*t,t=1; ans+=t*t; p=64*n*n*m*m; t=gcd(ans,p); ans/=t;p/=t; printf("%llu/%llu\n",ans,p); }
相关文章推荐
- 【NOI2017模拟4.5】无限棋盘
- 【NOI2017模拟4.5】无限棋盘【哈希,字符串,倍增】
- [JZOJ5045]无限棋盘
- 【JZOJ5046】【NOI2017模拟4.5】机器人游戏
- 【jzoj5045】【无限棋盘】【哈希】
- 【JZOJ5036】【NOI2017模拟3.30】原谅
- jzoj5043 【NOI2017模拟4.4】保持平衡 (可撤销贪心)
- 【JZOJ5180】【NOI2017模拟6.29】呵呵
- 【JZOJ5037】【NOI2017模拟3.30】轮回
- [JZOJ100019] 【NOI2017模拟6.26】A
- 【jzoj5306】【NOIP2017提高A组模拟8.18】【棋盘游戏】
- JZOJ 5043. 【NOI2017模拟4.4】保持平衡
- JZOJ 100019【NOI2017模拟6.26】A
- [JZOJ5044]【NOI2017模拟4.4】Sone0
- 【JZOJ5040】【NOI2017模拟4.2】押韵
- 【JZOJ5037】【NOI2017模拟3.30】轮回
- [JZOJ100003]【NOI2017模拟.4.1】 Tree
- 【JZOJ5039】【NOI2017模拟4.2】查询
- 【JZOJ 100019】【NOI2017模拟6.26】A
- [JZOJ5027]【NOI2017模拟3.25】历史行程