CodeForces 1065E. Side Transmutations 计数
2024-09-26 22:28:18
昨天不该早点走的....
首先操作限制实际上是一个回文限制
每个$b[i] - b[i - 1]$互不干扰,不妨设这个串关于中心点对称的这么一对区间的串分别为$(S_1, S_2)$
题目的限制相当与存在$(T_1, T_2)$使得$T_1 = inv(S_2) \;and\;T_2 = inv(S_1)$
考虑一对串$(S_1, S_2)$被计数多少次,我们分类讨论一下
一个长为$L$的子串的方案数为$S^L$,即为$f(L)$
一个长为$L$,字符集为$S$的区间,形成回文串的方案数为$S^{\frac{L +1}{2}}$,记为$g(L)$
如果$(S_1, S_2)$中有两个回文串,会被算重0次,否则都会被算重1次
那么方案数为$(f(L)^2 - g(L)^2) / 2 + g(L) * g(L)$
化简一下,$f(L) * (f(L) + 1) / 2$
复杂度$O(n \log n)$
#include <vector>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
namespace remoon {
#define re register
#define de double
#define le long double
#define ri register int
#define ll long long
#define sh short
#define pii pair<int, int>
#define mp make_pair
#define pb push_back
#define tpr template <typename ra>
#define rep(iu, st, ed) for(ri iu = st; iu <= ed; iu ++)
#define drep(iu, ed, st) for(ri iu = ed; iu >= st; iu --)
extern inline char gc() {
static char RR[], *S = RR + , *T = RR + ;
if(S == T) fread(RR, , , stdin), S = RR;
return *S ++;
}
inline int read() {
int p = , w = ; char c = gc();
while(c > '' || c < '') { if(c == '-') w = -; c = gc(); }
while(c >= '' && c <= '') p = p * + c - '', c = gc();
return p * w;
}
int wr[], rw;
#define pc(iw) putchar(iw)
tpr inline void write(ra o, char c = '\n') {
if(!o) pc('');
if(o < ) o = -o, pc('-');
while(o) wr[++ rw] = o % , o /= ;
while(rw) pc(wr[rw --] + '');
pc(c);
}
tpr inline void cmin(ra &a, ra b) { if(a > b) a = b; }
tpr inline void cmax(ra &a, ra b) { if(a < b) a = b; }
tpr inline bool ckmin(ra &a, ra b) { return (a > b) ? a = b, : ; }
tpr inline bool ckmax(ra &a, ra b) { return (a < b) ? a = b, : ; }
}
using namespace std;
using namespace remoon; #define mod 998244353
#define iv2 499122177
#define sid 200050 inline int fp(int a, int k) {
int ret = ;
for( ; k; k >>= , a = 1ll * a * a % mod)
if(k & ) ret = 1ll * ret * a % mod;
return ret;
} int n, m, S;
int b[sid]; int main() {
n = read(); m = read(); S = read();
rep(i, , m) b[i] = read();
int ans = fp(S, n - (b[m] * ));
rep(i, , m) {
int L = b[i] - b[i - ];
ans = 1ll * ans * fp(S, L) % mod * (fp(S, L) + ) % mod * iv2 % mod;
}
write(ans);
return ;
}
最新文章
- HTML+CSS 项目总结
- [原]CentOS7部署osm2pgsql
- 一个App完成入门篇-终结篇(八)- 应用收官
- c/c++创建动态链接库
- Windows Azure Cloud Service (36) 在Azure Cloud Service配置SSL证书
- Apache 的 httpd.conf 详解
- android调用系统相机拍照并保存在本地
- 解决Eclipse中Java工程间循环引用而报错的问题
- PHPStorm 3.0 与服务器端代码同步配置
- SOAPUI请求及mockservice 使用
- mysql去掉字段字符中间空格
- (转)基于企业级证书的IOS应用打包升级功能介绍
- 修改UISearchBar背景颜色
- AJAX实现类似百度的搜索提示,自动补全和键盘、鼠标操作
- Redis 中文入库成功,读取数据写入文件乱码问题
- ABAP POH和POV事件中 获得屏幕字段的值
- Java中final、finally、finalize有什么区别?
- Python-10 字典dict
- JDK、CGlib动态代理详解
- css之操作属性
热门文章
- 【IIS】IIS中同时满足集成模式和经典模式
- 蓝色的oa模板html_综合信息服务管理平台OA模板——后台
- Tinyos Makerules解读
- 关于linux系统如何实现fork的研究(一)【转】
- C# 开发(创蓝253)手机短信验证码接口
- PHP用imageTtfText函数在图片上写入汉字
- Netty框架入门
- socket.io插件调用的demo
- #题目:有10 台被监控主机、一台监控机,在监控机上编写脚本,一旦某台被监控机器/ 分区适用率大于80%, 就发邮件报警放到crontab 里面, 每10 分钟检查一次
- Window文本在Linux中出现的^M问题