没错,标签就是暴力。

首先发现棱上的所有词长度都相等,枚举长度 \(len\)。

然后发现这些词中只有第一个字符和最后一个字符比较重要(只有这两个位置会与别的串衔接,中间的是啥无所谓)。

令 \(cnt_{i,j}\) 为第一个字符是 \(i\),最后一个字符是 \(j\) 的词的个数。注意的是一个串反过来也算一个合法的串(题意说了正反读都行),但是如果这个反串也在输入中被给出了那就不重复算了。

容易想到 \(O(|\Sigma|^8len)\) 的最暴力做法:枚举八个顶点。

下面还有六次方五次方的部分分,略过。直接讲 \(O(|\Sigma|^4len)\) 的正解。

假如这个立方体是 \(ABCD-A'B'C'D'\),枚举 \(A,C,B',D'\) 上的字符。对于每个剩下的顶点,与它相邻的三个顶点已经被枚举到了。

问题就是快速求每个剩下的顶点的方案数。

再计算 \(tot_{i,j,k}\) 为相邻三个字符是 \(i,j,k\) 的方案数。也可以四次方解决。

这样常数不够优秀,注意到预处理时 \(i,j,k\) 时顺序没啥大关系,计算时 \(A,C,B',D'\) 的顺序也没啥大关系(乘个系数就好了),所以可以有个 \(\frac{1}{6}\) 的常数。

那就做完了。

#include<bits/stdc++.h>
using namespace std;
const int maxn=100010,mod=998244353,val[2][2][2]={{{24,12},{12,4}},{{12,6},{4,1}}};
#define lson o<<1,l,mid
#define rson o<<1|1,mid+1,r
#define FOR(i,a,b) for(int i=(a);i<=(b);i++)
#define ROF(i,a,b) for(int i=(a);i>=(b);i--)
#define MEM(x,v) memset(x,v,sizeof(x))
inline int read(){
int x=0,f=0;char ch=getchar();
while(ch<'0' || ch>'9') f|=ch=='-',ch=getchar();
while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();
return f?-x:x;
}
int n,cnt[62][62],tot[62][62][62],l[maxn],ans;
char s[maxn][13];
bool pali[maxn];
map<string,bool> vis;
inline int id(char c){
if(c>='a' && c<='z') return c-'a';
if(c>='A' && c<='Z') return c-'A'+26;
if(c>='0' && c<='9') return c-'0'+52;
}
int main(){
n=read();
FOR(i,1,n){
scanf("%s",s[i]);
l[i]=strlen(s[i]);
pali[i]=true;
FOR(j,0,l[i]-1) if(s[i][j]!=s[i][l[i]-1-j]) pali[i]=false;
}
FOR(len,3,10){
MEM(cnt,0);MEM(tot,0);
vis.clear();
int upr=0;
FOR(i,1,n) if(l[i]==len){
if(vis[string(s[i])]) continue;
string tmp=string(s[i]);
reverse(tmp.begin(),tmp.end());
vis[tmp]=true;
cnt[id(s[i][0])][id(s[i][l[i]-1])]++;
if(!pali[i]) cnt[id(s[i][l[i]-1])][id(s[i][0])]++;
upr=max(upr,id(s[i][0]));
upr=max(upr,id(s[i][l[i]-1]));
}
FOR(i,0,upr) FOR(j,i,upr) FOR(k,j,upr) FOR(l,0,upr)
tot[i][j][k]=(tot[i][j][k]+1ll*cnt[i][l]*cnt[j][l]%mod*cnt[k][l])%mod;
FOR(i,0,upr) FOR(j,i,upr) FOR(k,j,upr) FOR(l,k,upr){
int s=1ll*tot[i][j][k]*tot[i][j][l]%mod*tot[i][k][l]%mod*tot[j][k][l]%mod,hhh=0;
ans=(ans+1ll*s*val[i==j][j==k][k==l])%mod;
}
}
printf("%d\n",ans);
}

[CEOI2019]Cubeword(暴力)的更多相关文章

  1. P6845 [CEOI2019] Dynamic Diameter

    P6845 [CEOI2019] Dynamic Diameter 题意 一颗带权树,每次更改一条边的权,每次修改后求出最大直径.强制在线. 思路 \(O(n\log^2n)\) 的暴力做法. 根据经 ...

  2. zone.js - 暴力之美

    在ng2的开发过程中,Angular团队为我们带来了一个新的库 – zone.js.zone.js的设计灵感来源于Dart语言,它描述JavaScript执行过程的上下文,可以在异步任务之间进行持久性 ...

  3. [bzoj3123][sdoi2013森林] (树上主席树+lca+并查集启发式合并+暴力重构森林)

    Description Input 第一行包含一个正整数testcase,表示当前测试数据的测试点编号.保证1≤testcase≤20. 第二行包含三个整数N,M,T,分别表示节点数.初始边数.操作数 ...

  4. HDU 5944 Fxx and string(暴力/枚举)

    传送门 Fxx and string Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Othe ...

  5. 1250 Super Fast Fourier Transform(湘潭邀请赛 暴力 思维)

    湘潭邀请赛的一题,名字叫"超级FFT"最终暴力就行,还是思维不够灵活,要吸取教训. 由于每组数据总量只有1e5这个级别,和不超过1e6,故先预处理再暴力即可. #include&l ...

  6. fragment+viepager 的简单暴力的切换方式

    这里是自定义了一个方法来获取viewpager private static ViewPager viewPager; public static ViewPager getMyViewPager() ...

  7. ACM: Gym 101047M Removing coins in Kem Kadrãn - 暴力

     Gym 101047M Removing coins in Kem Kadrãn Time Limit:2000MS     Memory Limit:65536KB     64bit IO Fo ...

  8. uoj98未来程序改 纯暴力不要想了

    暴力模拟A了,数据还是良(shui)心(shui)的 90分的地方卡了半天最后发现一个局部变量被我手抖写到全局去了,,, 心碎*∞ 没什么好解释的,其实只要写完表达式求值(带函数和变量的),然后处理一 ...

  9. 开源服务专题之------ssh防止暴力破解及fail2ban的使用方法

    15年出现的JAVA反序列化漏洞,另一个是redis配置不当导致机器入侵.只要redis是用root启动的并且未授权的话,就可以通过set方式直接写入一个authorized_keys到系统的/roo ...

随机推荐

  1. 如何使用pm2一键部署node应用

    准备工作 准备一台linux服务器(本文档以阿里centos为例) 安装nodejs.git.pm2等环境 项目代码 本地已经安装用于连接 Linux 实例的工具,如 Xshell 基本流程 前两步传 ...

  2. linux服务器上配置进行kaggle比赛的深度学习tensorflow keras环境详细教程

    本文首发于个人博客https://kezunlin.me/post/6b505d27/,欢迎阅读最新内容! full guide tutorial to install and configure d ...

  3. Spring Boot2 系列教程(二十二)整合 MyBatis 多数据源

    关于多数据源的配置,前面和大伙介绍过 JdbcTemplate 多数据源配置,那个比较简单,本文来和大伙说说 MyBatis 多数据源的配置. 其实关于多数据源,我的态度还是和之前一样,复杂的就直接上 ...

  4. 使用celery执行Django串行异步任务

    Django项目有一个耗时较长的update过程,希望在接到请求运行update过程的时候,Django应用仍能正常处理其他的请求,并且update过程要求不能并行,也不能漏掉任何一个请求 使用cel ...

  5. make 命令与 Makefile

    make 是一个工具程序,通过读取 Makefile 文件,实现自动化软件构建.虽然现代软件开发中,集成开发环境已经取代了 make,但在 Unix 环境中,make 仍然被广泛用来协助软件开发.ma ...

  6. windows linux 子系统及windows terminal的使用。

    windows linux 子系统及windows terminal的使用. windows linux (wsl) 其实windows早就为我们准备好了子系统,但是我们的应用商店经常挂掉.因此都用不 ...

  7. layui 学习笔记一:layui table 查询、新增、编辑、删除

    一.table数据的呈现(对应查询) 页面代码: @{ ViewBag.Title = "TableGrid"; } @section styles{ <link href= ...

  8. 面试题-JavaScript交换两个变量的方法

    在平时的业务开发或者面试过程中,经常会遇到交换两个变量这种问题,于是,个人总结以下几种交换变量的方法: 1.方案一 使用一个临时变量来交换  2.方案二 使用ES6解构赋值语法来交换 3.方案三利用数 ...

  9. Android Activity 开发常用技巧整理

    1.设置 Activity 背景色为透明 在style.xml里面声明: <style name="TranslucentActivityStyle" parent=&quo ...

  10. 第三方库Mantle的源码解析

    Mantle是一个用于简化Cocoa或Cocoa Touch程序中model层的第三方库.通常我们的应该中都会定义大量的model来表示各种数据结构,而这些model的初始化和编码解码都需要写大量的代 ...