# 3164 "CEOI2019"큐브 가사

제목 설명

문제 해결

우리는 편지가 끝과 끝이 무엇인지에 대해 관심이 있기 때문에 우리가 기록 할 수 있도록 첫 번째 분류의 길이에 따라, 그래서 우리는 아래와 디엠 퍼시스 모든 것을 넣을 수 있습니다 각 문자열의 장점과 단점의 길이, 긍정과 부정으로 읽을 수 있습니다 g [ a ] [ b ] 갈고리] 의 시작을 나타낸다 a , 종료 b 문자열 얼마나 많은.

그런 다음이 큐브는, 우리는 모든 각도, 다음, 통계 프로그램을 고려할 수 있지만, 사실 우리가 처음, 아래 프로그램 모양의 그림의 수를 셀 수있는 가장 폭력적인 열거 교차로 넣어의 상관없이 가장자리 경우 그 나머지 정점 b , c , d B, C, D 프로그램의 많은 종류의, 우리는이 숫자를 넣어 계획을 다음 방법, f [ b ] [ c ] [ d ] F [B] [C], [D] .

그리고 우리가 아래 모양 찾을 수 있습니다, 우리는로 큐브 수 4 4 번째 그림 패턴, 정점 A , B , C , D A, B, C, D , 만약 정점 채우기의 나머지 a , b , c , d A, B, C, D 그 프로그램 번호는 f [ a ] [ b ] [ c ] × f [ a ] [ b ] [ d ] × f [ a ] [ c ] [ d ] × f [ b ] [ c ] [ d ] F [A] [B] [C] \ F 배 [A] [B] [D] \ F 배 [A] [C], [D], [B] F \ 시간 [C], [D] .

그런 다음 우리는 종종 원하는대로 카드가 필요합니다 f 에프 의 시간 b c d B \ C \ D를 即可,求方案数的时候让 a b c d a \le b \le c \le d 即可,注意求方案数要乘上排列数。

代码

#include <bits/stdc++.h>
#define U unsigned long long
using namespace std;
const U B=793999;
const int P=998244353,N=62;
char ch[15];map<U,int>mp;
int n,m,g[15][N][N],f[N][N][N],t[N],s;
int X(int x){return x>=P?x-P:x;}
int G(char x){
	if (x>='a' && x<='z') return x-'a';
	if (x>='A' && x<='Z') return x-'A'+26;
	return (x^48)+52;
}
int main(){
	cin>>n;
	for (int i=1;i<=n;i++){
		scanf("%s",ch+1);
		m=strlen(ch+1);U v=0;
		for (int j=1;j<=m;j++) v=v*B+ch[j];
		if (!mp.count(v))
			mp[v]=1,g[m][G(ch[1])][G(ch[m])]++;
		v=0;
		for (int j=m;j;j--) v=v*B+ch[j];
		if (!mp.count(v))
			mp[v]=1,g[m][G(ch[m])][G(ch[1])]++;
	}
	for (int x=3;x<=10;x++){
		memset(f,0,sizeof f);
		for (int a=0;a<N;a++)
			for (int b=0;b<N;b++) if (g[x][a][b])
				for (int c=b;c<N;c++) if (g[x][a][c])
					for (int d=c;d<N;d++) if (g[x][a][d])
						f[b][c][d]=X(f[b][c][d]+1ll*g[x][a][b]*g[x][a][c]%P*g[x][a][d]%P);
		int p=24;
		for (int a=0;a<N;a++){
			t[a]++;p/=t[a];
			for (int b=a;b<N;b++){
				t[b]++;p/=t[b];
				for (int c=b;c<N;c++) if (f[a][b][c]){
					t[c]++;p/=t[c];
					for (int d=c;d<N;d++){
						t[d]++;p/=t[d];
						s=X(s+1ll*p*f[a][b][c]%P*f[a][b][d]%P*f[a][c][d]%P*f[b][c][d]%P);
						p*=t[d];t[d]--;
					}
					p*=t[c];t[c]--;
				}
				p*=t[b];t[b]--;
			}
			p*=t[a];t[a]--;
		}
	}
	cout<<s<<endl;return 0;
}
发布了155 篇原创文章 · 获赞 5 · 访问量 1万+

추천

출처blog.csdn.net/Johnny817/article/details/104383348