2024年07月随便做做

news/2024/10/6 3:48:36/文章来源:https://www.cnblogs.com/imcaigou/p/18285817

Miscellaneous

*[2024.06.28] 珍珠

一个 \(n\) 个珠子的项链可翻转、可旋转,染 \(01\) 颜色,问本质不同的项链中,满足存在一段子串为给定 \(s\) ,这些项链的个数。

\(n\le 10^9,m=|s|,m\le 22\)

考虑带权 Burnside 引理,转换成:

\[\frac{1}{|G|}\sum_{g\in G} W(C(g)) \]

其中 \(W(S)=\sum_{c\in S}w(c)\)\(w(c)\)\(1\) 当且仅当 \(c\) 满足题目要求,否则为 \(0\)

对于后面的和式,我们可以将 \(G\) 考虑分为两部分。

\(\Delta=(2,3,\cdots,n,1),\rho = (n,n-1,\cdots, 1)\)

会发现一部分是未反转的部分,记为 \(G_1=\{\Delta^t|t\in \N^*\}\)

而另一部分是反转过的,记为 \(G_2=\{\Delta^t\circ \rho|t\in \N^*\}\)

会发现有循环和反转在环上的性质显然有:\(G_1\cup G_2=G,G_1\cap G_2=\empty\)

且因为 \(\Delta^n=\iota\),因此 \(|G_1|=|G_2|=n\)


首先考虑 \(G_2\) 部分的 \(\sum W(C(g))\) 怎么算。

考虑 \(n\) 的奇偶性,如果 \(n\) 为奇数,就只有一种情况,否则会出现两种情况。这里我们讨论奇数,因为偶数的情况类似,只是更加麻烦不易理解。

考虑 \(n\) 为奇数的情况,对于一个 \(t\)\(\Delta^t\circ \rho=(t,t-1,\cdots,1,n,n-1,\cdots,t+1)\)。因此\(C(\Delta^t\circ \rho)\) 中的串一定都是由两个回文串拼接成的,但是如果我们再将 \(\Delta^{-t}\) 作用在这些串上,一定会一一对应 \(C(\rho)\) 中的串,因为置换有逆,因此这个作用可以看作 \(C(\Delta^t\circ \rho)\)\(C(\rho)\) 的双射。

而且同时知道 \(w(c)=w(\Delta^{k}*c)\),结合双射可知有 \(W(C(\Delta^t\circ \rho))=W(C(\rho))\)

因此可知 \(\forall f,g\in G_2,W(C(f))=W(C(g))\)

所以我们只需要考虑 \(W(C(\rho))\) 也就是有多少个长度为 \(n\) 的回文串满足首尾拼接成环后出现 \(s\)\(s^R\)。正着不太好做,考虑反着算,即计算有多少串不满足条件。

考虑记扫描字符串的状态 \((x,y)\) 表示以当前顺序扫描到的字符串,\(x\) 为最长的后缀长度满足这个后缀是 \(s\) 的前缀,\(y\) 为最长的后缀长度满足这个后缀是 \(s^R\) 的前缀。会发现这些状态只有 \(O(m)\) 个,可以通过 AC 自动机或者 KMP 自动机维护。

因此可以先 \(O(2^m)\) 枚举前面的串,判断首位拼接是否合法并记录到状态各自的初始方案数,随后进行矩阵乘法,然后再在中心判断是否出现 \(s,s^R\) ,如果没有出现,即可计入答案。

这部分时间复杂度为 \(O(m^3\log_2 n+m2^m)\)

如果要考虑 \(n\) 为偶数则还需考虑一种情况,就是两个奇长度的回文串的拼接,这种情况只能转换成一个单字符再加上一个奇回文串的情况,和上面的计算方法同理。


随后是 \(G_1\) 部分,这部分是简单的。

存在三个性质,强度是递进的:

  • \(\Delta^t\) 中有 \(\gcd (t, n)\) 个置换环。
  • \(\Delta^t\)\(i\)\(i+\gcd (t,n)\) (如果存在)一定属于一个轮换。
  • \(\Delta^t\)\(\forall 1\le i\le \gcd (t,n)\) 归属的轮换各不相同。

证明是简单的初等数论知识。

拥有这三个性质,我们知道对于 \(\Delta^t\) 考虑 \(W(C(\Delta^t))\) 只需要考虑长度为 \(\gcd(t,n)\) 并满足首位拼接后出现 \(s\)\(s^R\),统计这样的串的个数即为 \(W(C(\Delta^t))\)

所以考虑 \(F(x)\) 表示长度为 \(x\) 并满足首位拼接后出现 \(s\)\(s^R\) 的串的个数。

\(F(x)\) 可以用矩阵乘法计算。同样先计算出从头到尾没出现过 \(s\)\(s^R\) 的串的个数再做减法,我们可以先钦定末尾的状态是什么,做完矩阵乘法后再取出同样状态位置上的数计入答案即可。

那么知道有:

\[\begin{aligned} &\sum_{g\in G_1} W(C(g)) \\ =&\sum_{t=1}^nW(C(\Delta^t)) \\ =&\sum_{t=1}^n F(\gcd (t,n)) \\ =&\sum_{t|n}F(t)\sum_{k=1}^{\frac{n}{t}}[\gcd (k,\frac{n}{t})=1] \\ =&\sum_{t|n}F(t)\varphi (\frac{n}{t}) \end{aligned} \]

时间复杂度 \(O(d(n)m^3\log_2 n)\)


总的时间复杂度是 \(O(d(n)m^3\log_2n+m2^m)\)

// Not afraid to dark.#include <bits/stdc++.h>
using namespace std;clock_t start_time, end_time;
#define GET_START start_time = clock ();
#define GET_END end_time = clock (); fprintf (stderr, "TIME COSSEMED : %0.3lf\n", 1.0 * (end_time - start_time) / CLOCKS_PER_SEC);
#define inline __inline__ __attribute__ ((always_inline))#define int long longnamespace io {int read_pos, read_dt; char read_char;inline int read (int &p = read_pos){p = 0, read_dt = 1; read_char = getchar ();while (! isdigit (read_char)){if (read_char == '-')read_dt = - 1;read_char = getchar ();}while (isdigit (read_char)){p = (p << 1) + (p << 3) + read_char - 48;read_char = getchar ();}return p = p * read_dt;}int write_sta[65], write_top;inline void write (int x){if (x < 0)putchar ('-'), x = - x;write_top = 0;dowrite_sta[write_top ++] = x % 10, x /= 10;while (x);while (write_top)putchar (write_sta[-- write_top] + 48);}int llen;inline int get_string (char c[], int &len = llen){len = 0;read_char = getchar ();while (read_char == ' ' || read_char == '\n' || read_char == '\r')read_char = getchar ();while (read_char != ' ' && read_char != '\n' && read_char != '\r'){c[++ len] = read_char;read_char = getchar ();}return len;}
}template < int SIZE > 
struct Automaton {int nex[SIZE + 5][2], len[SIZE + 5], tot;int a[SIZE + 5], cnt;inline void init (){nex[0][0] = nex[0][1] = len[0] = 0;tot = cnt = 0;}inline int new_node (){++ tot;nex[tot][0] = nex[tot][1] = len[tot] = 0;return tot;}inline void Insert (int x){static int u, fw;a[++ cnt] = x;u = tot;fw = nex[u][x];nex[u][x] = new_node ();nex[tot][0] = nex[fw][0];nex[tot][1] = nex[fw][1];}inline int to (int x, int c){return nex[x][c];}
};const int M = 22, mod = 1e9 + 7;int n, m, l, ans;
char s[M + 5], t[M + 5];Automaton < M + 1 > pre, suf;int cn;
vector < pair < int , int > > state;
map < pair < int , int > , int > st;struct matrix {int a[M << 1 | 1][M << 1 | 1];inline void init (int c = 0){for (int i = 0;i < cn;++ i)for (int j = 0;j < cn;++ j)a[i][j] = (i == j ? c : 0);}inline matrix friend operator * (const matrix a, const matrix b){static matrix res;static int i, j, k;static __int128 x;res.init ();for (i = 0;i < cn;++ i)for (j = 0;j < cn;++ j){for (k = 0, x = 0;k < cn;++ k)x += (__int128) a.a[i][k] * b.a[k][j];res.a[i][j] = x % mod;}return res;}matrix (int c = 0){init (c);}
};inline matrix power (matrix a, int p){matrix res (1);while (p > 0){if (p & 1)res = res * a;a = a * a;p >>= 1;}return res;
}
inline int power (int a, int p){int res = 1;while (p > 0){if (p & 1)res = res * a % mod;a = a * a % mod;p >>= 1;}return res;
}inline int nex (int x, int c){static int p, q;tie (p, q) = state[x];p = pre.to (p, c);q = suf.to (q, c);return st[make_pair (p, q)];
}
inline bool tar (int x){return state[x].first == m || state[x].second == m;
}inline void Calc_Reverse (){matrix res, g;int rt = 0;auto od_calc = [&] (){int T = 0;for (int i = 0, pt, j, u, v;i < cn;++ i)if (res.a[0][i]){u = i;for (pt = 0;pt < 2;++ pt){v = nex (u, pt);if (tar (v))continue;if (state[i].first >= state[i].second)for (j = state[i].first;j >= 1;-- j){v = nex (v, s[j] - '0');if (tar (v))goto E_1;}elsefor (j = state[i].second - 1;j >= 0;-- j){v = nex (v, s[m - j] - '0');if (tar (v))goto E_1;}rt = (rt + res.a[0][i]) % mod;T += res.a[0][i];E_1 : ;}}};for (int i = 0, c;i < cn;++ i)for (c = 0;c < 2;++ c)if (! tar (i) && ! tar (nex (i, c)))g.a[i][nex (i, c)] = 1;if (n & 1){int t = min (m, n >> 1);for (int i = 0, j, u, v;i < (1 << t);++ i){for (j = t - 1, v = 0;j >= 0;-- j){v = nex (v, i >> j & 1);if (tar (v))goto E_2;}for (j = u = 0;j < t;++ j){u = nex (u, i >> j & 1);v = nex (v, i >> j & 1);if (tar (v))goto E_2;}++ res.a[0][u];E_2 : ;}res = res * power (g, (n >> 1) - t);od_calc ();rt = (power (2, (n + 1) >> 1) - rt + mod) * n % mod;} else {int t = min (m, n >> 1);for (int i = 0, j, u, v;i < (1 << t);++ i){for (j = t - 1, v = 0;j >= 0;-- j){v = nex (v, i >> j & 1);if (tar (v))goto E_3;}for (j = u = 0;j < t;++ j){u = nex (u, i >> j & 1);v = nex (v, i >> j & 1);if (tar (v))goto E_3;}++ res.a[0][u];E_3 : ;}res = res * power (g, (n >> 1) - t);for (int i = 0, j, u;i < cn;++ i)if (res.a[0][i]){u = i;if (state[i].first >= state[i].second){for (j = state[i].first;j >= 1;-- j){u = nex (u, s[j] - '0');if (tar (u))goto E_4;}} else{for (j = state[i].second - 1;j >= 0;-- j){u = nex (u, s[m - j] - '0');if (tar (u))goto E_4;}}rt = (rt + res.a[0][i] % mod) % mod;E_4 : ;}res.init ();t = min (m, (n >> 1) - 1);for (int i = 0, j, u, v, s, pt;i < (1 << t);++ i){for (j = t - 1, u = 0;j >= 0;-- j){u = nex (u, i >> j & 1);if (tar (u))goto E_5;}for (pt = 0;pt < 2;++ pt){v = nex (u, pt);if (tar (v))goto E_6;for (j = s = 0;j < t;++ j){s = nex (s, i >> j & 1);v = nex (v, i >> j & 1);if (tar (v))goto E_6;}++ res.a[0][s];E_6 : ;}E_5 : ;}res = res * power (g, (n >> 1) - 1 - t);od_calc ();rt = (power (2, n >> 1) + power (2, (n >> 1) + 1) - rt + mod) * (n >> 1) % mod;}ans = (ans + rt) % mod;
}
inline void Calc_inord (){vector < int > fac;int r = n;for (int i = 2;i * i <= r;++ i)while (r % i == 0){if (fac.empty () || fac.back () != i)fac.push_back (i);r /= i;}if (r > 1)fac.push_back (r);auto phi = [&] (const int &x){int res = x;for (int y : fac)if (x % y == 0)res /= y, res *= (y - 1);return res;};matrix A, g;for (int i = 0, c;i < cn;++ i)for (c = 0;c < 2;++ c)if (! tar (i) && ! tar (nex (i, c)))g.a[i][nex (i, c)] = 1;auto F = [&] (const int x){int res = 0;A.init ();for (int i = 0;i < cn;++ i){if (max (state[i].first, state[i].second) == m)continue;A.a[i][i] = 1;}A = A * power (g, x);for (int i = 0;i < cn;++ i)res = (res + A.a[i][i]) % mod;return (power (2, x) - res + mod) % mod;};int rt = 0;for (int i = 1;i * i <= n;++ i)if (n % i == 0){rt = (rt + phi (n / i) * F (i) % mod) % mod;if (n / i != i)rt = (rt + phi (i) * F (n / i) % mod) % mod;}ans = (ans + rt) % mod;
}signed main (){GET_STARTio::read (n), io::read (m);io::get_string (s);if (n == 1)return putchar ('1'), putchar ('\n'), 0;if (n == 2){if (m == 2)return putchar ('1'), putchar ('\n'), 0;elsereturn putchar ('2'), putchar ('\n'), 0;}pre.init ();for (int i = 1;i <= m;++ i)pre.Insert (s[i] - '0'), suf.Insert (s[m - i + 1] - '0');state.push_back (make_pair (0, 0));for (int i = 1, j, u;i <= m;++ i){for (j = 1, u = 0;j <= i;++ j)u = suf.to (u, s[j] - '0');state.push_back (make_pair (i, u));for (j = m, u = 0;j > m - i;-- j)u = pre.to (u, s[j] - '0');state.push_back (make_pair (u, i));}sort (state.begin (), state.end ());state.erase (unique (state.begin (), state.end ()), state.end ());cn = (int) state.size ();for (int i = 0;i < cn;++ i)st[state[i]] = i;Calc_Reverse ();Calc_inord ();io::write (ans * power ((n << 1) % mod, mod - 2) % mod), putchar ('\n');GET_ENDreturn 0;
}

Codeforces 1987G1 - Spinning Round (Easy Version)

考虑对于以 \(1\) 为根的情况,一定可以分成两段不交的路径,分别线段树维护单调栈扫前后缀即可。

但是需要注意的是不以 \(1\) 为根的情况,这时发现对于一段前缀,如果最终不以 \(1\) 为根且要以自身为一段路径,一定会以后面第一个大于当前后缀最大值的点为根,对于每个前缀这个点是唯一的,因此扫后缀是顺便记录即可。扫前缀时同理。

Submission #268435009 - Codeforces

Codeforces 1987G2 - Spinning Round (Hard Version)

不再考虑复杂的线段树。

建出笛卡尔树,发现如果不是连向笛卡尔树上的父亲,一定就会连向从它往上的祖先中,第一个改变指向的点的父亲。

于是考虑 DP 方程,记 \(f(x,0/1/2)\) 表示 \(x\) 子树中最终从左侧跳出的最长路径、最终从右侧跳出的最长路径、分别从左右两边跳出的两条路径和的最大值。

转移是简单的。

Submission #268861885 - Codeforces

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/738766.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

结合RNN与Transformer双重优点,深度解析大语言模型RWKV

RWKV在多语言处理、小说写作、长期记忆保持等方面表现出色,可以主要应用于自然语言处理任务,例如文本分类、命名实体识别、情感分析等。本文分享自华为云社区《【云驻共创】昇思MindSpore技术公开课 RWKV 模型架构深度解析》,作者:Freedom123。 一、前言 Transformer模型作…

VMware vSphere Tanzu部署_16_TKC集群节点VM密码获取

SupervisorControlPlaneVM密码获取 通过SSH方式登录vcentervcenter开启SSH服务通过SSH工具登录vcenter执行获取密码脚本在vcenter shell模式下执行/usr/lib/vmware-wcp/decryptK8Pwd.py命令WARNING! The remote SSH server rejected X11 forwarding request. Connected to serv…

空洞文件

实际上这些数据并没有被存储在磁盘上。当创建一个空洞文件时,文件系统会记录这些“空洞”,但并不会在物理介质上实际分配和保存未使用的空间,从而节省了实际的存储空间。 举例来说,如果你创建一个大小为1GB的空洞文件,其中写入了大量的零字节据,实际上只有少量的数据(例…

Box,一个字典操作python库

Box介绍 Box 是一个让字典操作变得异常简单与直观,支持通过属性访问字典内容的库。特点概述属性访问Box 允许用户像访问对象属性一样访问字典的值,提升了代码的可读性和易用性。无缝嵌套自动将嵌套的字典转换为 Box 对象,使得处理复杂字典结构变得轻而易举。灵活性强支持多种…

(四)JS逆向——中国观鸟网

爬取观鸟网的信息 有sign值,timestamp和requestid,要看这些值是怎么生成的 载荷有加密的数据 返回值也经过加密 搜索requestid,找到了eval加密的代码,通过解密,就能找到生成这些值的代码段 代码格式化后,找到了这几个值的生成位置 requestid的生成是随机值,timestamp是时…

vscode插件安装好用

本文来自博客园,作者:prince11,转载请注明原文链接:https://www.cnblogs.com/prince11/p/18285764

java List子父级集合转List树工具类

java List集合转Tree集合 1.创建泛型工具类package com.demo;import org.springframework.util.CollectionUtils;import java.lang.reflect.Field; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; import java.util…

博客屋网址导航自适应主题php源码

博客屋网址导航自适应主题php源码v1.0是一个以PHP+MySQL进行开发的网址导航源码。模板源码后台开源无加密,可二次开发,前端响应式自适应多端屏幕。主题源码适合个人建站技术,个人博客论坛,个人日记分享等个人网站内容。站长也可以修改成其他行业的内容目录导航。演示地址ht…

【vue】为什么v-for中需要一个key呢?

通过key值来区分循环中的子内容

在wsl中部署puppeteer的相关笔记

二. 缺少依赖问题反复提示缺少各种依赖,到处搜刮一顿操作之后是没问题了,但也不知道哪些是无所谓的 apt install -y gconf-service libc6 libcairo2 libdbus-1-3 libexpat1 libfontconfig1 libgcc1 libgdk-pixbuf2.0-0 libglib2.0-0 libgtk-3-0 libstdc++6 libx11-6 apt inst…

《计算机组成与系统结构(第二版) 裘雪红 李伯成 西安电子科技大学出版社》课后习题答案(带解析)(七)

此系列答案配套《计算机组成与系统结构(第二版) 裘雪红 李伯成 西安电子科技大学出版社》一书相关内容。所有内容为博主个人编辑,仅作参考学习交流之用,转载请注明出处。如发现错误,请联系博主及时勘误。如有侵权行为,博主将立即下架全部内容。声明:此系列答案配套《计…

【设计模式(二)】创建型模式--抽象工厂模式

创建型模式的主要关注点是“怎样创建对象?”,它的主要特点是“将对象的创建与使用分离”。这样可以降低系统的耦合度,使用者不需要关注对象的创建细节。抽象工厂模式也是⼀种创建型设计模式,提供了一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类 抽象工厂…