ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Osmosmjerka

2022-07-31 18:00:20  阅读:176  来源: 互联网

标签:return int s2 Osmosmjerka wh inline s1


link

出题人是卡常狗。靠。

首先题目中的方向是八方向,即包括右上右下左上左下(不然发现样例一过不去),由于需要判断字符串是否相等,想到使用哈希来加速这一过程。但是呢要求的字符串长度又很长,长宽不等导致无法利用循环的性质来砍掉无用部分(事实上我连这部分都没写出来,呜呜呜)。正解是倍增哈希,我还是第一次听说哈希还可以倍增,但确实挺好理解的也挺有效的(甚至比之前那个东西还好写得多)。但是咋也卡不过去,放弃了。

放我自己T了一个点的代码。

#include<bits/stdc++.h>
//#define feyn
#define int long long
const int N=510;
const int M=33;
const int mod=1e9+7;
using namespace std;
inline void read(int &wh){
    wh=0;int f=1;char w=getchar();
    while(w<'0'||w>'9'){if(w=='-')f=-1;w=getchar();}
    while(w<='9'&&w>='0'){wh=wh*10+w-'0';w=getchar();}
    wh*=f;return;
}

inline int gcd(int s1,int s2){
	return s2==0?s1:gcd(s2,s1%s2);
}

char a[N][N];
struct node{int x,y;}nxt[N][N][M];
int m,n,len,e[M],data[N][N][M];

map<int,int>p;
inline void c(int &x,int &y){
	if(x==0)x=m;if(y==0)y=n;
	if(x>m)x=1;if(y>n)y=1;
}
inline int qpow(int s1,int s2){
	if(s2==1)return s1;
	int an=qpow(s1,s2>>1);
	if(s2&1)return an*an%mod*s1%mod;
	else return an*an%mod;
}
int qwq;
inline void solve(int xx,int yy){
	for(int i=1;i<=m;i++){
		for(int j=1;j<=n;j++){
			int x=i+xx,y=j+yy;c(x,y);
			nxt[i][j][0]=(node){x,y};
			data[i][j][0]=a[i][j];
		}
	}
	for(int i=1;i<=qwq;i++){
		for(int j=1;j<=m;j++){
			for(int k=1;k<=n;k++){
				node now=nxt[j][k][i-1];
				int x=now.x,y=now.y;
				nxt[j][k][i]=nxt[x][y][i-1];
				data[j][k][i]=data[j][k][i-1]*e[i-1]+data[x][y][i-1];
			}
		}
    }
    int pq[M],now_=len;
    for(int k=qwq;k>=0;k--){
    	if((1ll<<k)<=now_){
    		pq[k]=qpow(26,now_);
    		now_-=(1ll<<k);
		}
	}
    for(int i=1;i<=m;i++){
    	for(int j=1;j<=n;j++){
    		int ndata=0,now=len,px=i,py=j;
    		for(int k=qwq;k>=0;k--){
    			if((1ll<<k)<=now){
    				ndata=ndata*pq[k]+data[px][py][k];
    				now-=(1ll<<k);
    				node pl=nxt[px][py][k];
    				px=pl.x,py=pl.y;
				}
			}
			p[ndata]++;
		}
	}
}

signed main(){
	
	#ifdef feyn
	freopen("in.txt","r",stdin);
	#endif
	
	read(m);read(n);read(len);
	while((1ll<<qwq)<=len)qwq++;
	for(int i=1;i<=m;i++){
		scanf("%s",a[i]+1);
		for(int j=1;j<=n;j++){
			a[i][j]-='a';
		}
	}
	e[0]=26;
	for(int i=1;i<M;i++)e[i]=e[i-1]*e[i-1]%mod;
	
	for(int i=-1;i<=1;i++){
		for(int j=-1;j<=1;j++){
			if(i==0&&j==0)continue;
			solve(i,j);
		}
	}
	
	int all=m*n*8,ans=0;all=all*all;
	for(map<int,int>::iterator it=p.begin();it!=p.end();it++){
		ans+=(it->second)*(it->second);
	}
	int g=gcd(all,ans);
	printf("%lld/%lld\n",ans/g,all/g);
	
	return 0;
}

标签:return,int,s2,Osmosmjerka,wh,inline,s1
来源: https://www.cnblogs.com/dai-se-can-tian/p/16537701.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有