Bzoj3555: [Ctsc2014]企鹅QQ

题面

传送门

Sol

\(hash\)+排序

# include <bits/stdc++.h>
# define IL inline
# define RG register
# define Fill(a, b) memset(a, b, sizeof(a))
using namespace std;
typedef long long ll;

template <class Int>
IL void Input(RG Int &x){
	RG int z = 1; RG char c = getchar(); x = 0;
	for(; c < '0' || c > '9'; c = getchar()) z = c == '-' ? -1 : 1;
	for(; c >= '0' && c <= '9'; c = getchar()) x = (x << 1) + (x << 3) + (c ^ 48);
	x *= z;
}

const int maxn(3e4 + 5);
const int maxm(205);
const int seed1(1402);
const int seed2(1707);

int n, m, s, id[maxn], ans;
ll p1[2][maxn][maxm], p2[2][maxn][maxm], key1[maxn], key2[maxn];
char name[maxn][maxm];

IL int Cmp(RG int x, RG int y){
	return key1[x] == key1[y] ? key2[x] < key2[y] : key1[x] < key1[y];
}

int main(RG int argc, RG char* argv[]){
	Input(n), Input(m), Input(s);
	for(RG int i = 1; i <= n; ++i){
		scanf(" %s", name[i] + 1), id[i] = i;
		for(RG int j = 1; j <= m; ++j){
			p1[0][i][j] = p1[0][i][j - 1] * seed1 + name[i][j];
			p1[1][i][j] = p1[1][i][j - 1] * seed2 + name[i][j];
		}
		for(RG int j = m; j; --j){
			p2[0][i][j] = p2[0][i][j + 1] * seed1 + name[i][j];
			p2[1][i][j] = p2[1][i][j + 1] * seed2 + name[i][j];
		}
	}
	for(RG int j = 1; j <= m; ++j){
		for(RG int i = 1; i <= n; ++i){
			key1[i] = p1[0][i][j - 1] * seed1 + p2[0][i][j + 1] * seed2;
			key2[i] = p1[1][i][j - 1] * seed2 + p2[1][i][j + 1] * seed1;
		}
		sort(id + 1, id + n + 1, Cmp);
		for(RG int p = 2, num = 1, pre = id[1]; p <= n; ++p){
			RG int i = id[p];
			if(key1[i] == key1[pre] && key2[i] == key2[pre]) ans += num, ++num;
			else num = 1;
			pre = i;
		}
	}
	printf("%d\n", ans);
	return 0;
}

posted @ 2018-04-13 19:19  Cyhlnj  阅读(103)  评论(0编辑  收藏  举报