码迷,mamicode.com
首页 > 其他好文 > 详细

$5.3$ 签到题 题解报告

时间:2021-05-23 23:37:29      阅读:0      评论:0      收藏:0      [点我收藏+]

标签:lang   contain   get   mes   字符串   while   struct   情况   出现   

\(5.3\) 签到题 题解报告

得分情况

\(T1\) : \(40\ Pts\)

\(T2\) : \(70\ Pts\)

\(T3\) : \(30\ Pts\)

总分 : \(140\ Pts\)

\(T1\)

读完题先写了个暴力 然后又看 十分多钟弄出了上面那个式子 然后发现这个递推和暴力的复杂度是一样的 想到矩阵优化 但是矩阵求不出来 再然后就没有然后了

写完其他题的暴力 再回来尝试推数学通式 化简了一个多小时之后 推出来一个式子 然后发现不可做 因为涉及到除法 但是模数不保证是质数 暴力 \(40\)

递推式: \(f_i = f_{i - 1} \times x + i\)

正解矩阵快速幂 矩阵:

\[\begin{bmatrix} f_{i - 1} & i - 1 & 1 \end{bmatrix} \times \begin{bmatrix} x & 0 & 0 \\ 1 & 1 & 0 \\ 1 & 1 & 1 \end{bmatrix} = \begin{bmatrix} f_i & i & 1 \end{bmatrix} \]

/*
  Time: 5.3
  Worker: Blank_space
  Source: #1: 签
*/
/*--------------------------------------------*/
#include<cstdio>
#include<cstring>
#define int long long
/*--------------------------------------头文件*/

/*------------------------------------常量定义*/
int n, x, mod, ans = 1;
struct node {
	int a[4][4];
	node() {memset(a, 0, sizeof a);}
	void re() {a[1][1] = a[2][2] = a[3][3] = 1;}
	void pre() {a[1][1] = x; a[2][1] = a[2][2] = a[3][2] = a[3][3] = 1;}
};
/*------------------------------------变量定义*/
inline int read() {
	int x = 0, f = 1; char ch = getchar();
	while(ch < ‘0‘ || ch > ‘9‘) {if(ch == ‘-‘) f = -1; ch = getchar();}
	while(ch >= ‘0‘ && ch <= ‘9‘) {x = (x << 3) + (x << 1) + (ch ^ 48); ch = getchar();}
	return x * f;
}
/*----------------------------------------快读*/
node operator * (const node &x, const node &y) {
	node z;
	for(int i = 1; i <= 3; i++) for(int k = 1; k <= 3; k++)
		for(int j = 1; j <= 3; j++) z.a[i][j] = (z.a[i][j] + x.a[i][k] * y.a[k][j] % mod) % mod;
	return z;
}
node operator ^ (node &x, int y) {
	node res; res.re();
	for(; y; x = x * x, y >>= 1) if(y & 1) res = res * x;
	return res;
}
/*----------------------------------------函数*/
signed main() {
	n = read(); x = read(); mod = read();
	node T; T.pre();
	T = T ^ (n - 1);
	printf("%lld", ((T.a[1][1] + T.a[2][1] * 2) % mod + T.a[3][1]) % mod);
	return 0;
}

\(T2\)

暴力枚举因子 构造倍数 范围开大 \(70\ Pts\)

正解没听懂

\(T3\)

看完题写了一个复杂度大概是 \(O(n ^ 3 2^n)\) 级别的算法 然后过了三十分...

正解

长度为 \(l\) 的子串 共 \(2^l\) 种 长度为 \(N\) 的字符串 最多有 \(N - l + 1\) 个本质不同 长度为 \(l\) 的子串 如果 \(2 ^ l > N - l + 1\) 那么一定存在长度为 \(l\)\(01\)\(B‘\) 没有在 \(A\) 中出现过 \(1 \leq N \leq 24\)\(l = 24\) 的时候总能满足条件 所以可能的 \(B\) 有不到 \(2 ^ {24}\)

参照其他通过的人的写法 预处理每一长度下每一状态的串 表示的方法也是某一状态 迭代加深枚举长度

/*
  Time: 5.3
  Worker: Blank_space
  Source: 3394: 题
*/
/*--------------------------------------------*/
#include<cstdio>
#include<cstring>
/*--------------------------------------头文件*/
const int C = 1e6 + 7;
/*------------------------------------常量定义*/
int n, d, c[C << 1];
char s[C << 1];
/*------------------------------------变量定义*/
inline int read() {
	int x = 0, f = 1; char ch = getchar();
	while(ch < ‘0‘ || ch > ‘9‘) {if(ch == ‘-‘) f = -1; ch = getchar();}
	while(ch >= ‘0‘ && ch <= ‘9‘) {x = (x << 3) + (x << 1) + (ch ^ 48); ch = getchar();}
	return x * f;
}
/*----------------------------------------快读*/
bool dfs(int t, int S) {
	if(t > d) {if(!((c[S] >> d) & 1)) {for(int i = d - 1; i >= 0; i--) printf("%d", (S >> i) & 1); return 1;} return 0;}
	if(dfs(t + 1, S << 1)) return 1; if(dfs(t + 1, S << 1 | 1)) return 1; return 0;
}
/*----------------------------------------函数*/
int main() {
	scanf("%s", s); n = strlen(s);
	for(int i = 0, S = 0; i < n; i++, S = 0) for(int j = 1; j <= 21 && i + j <= n; j++)
		S = (S << 1 | s[i + j - 1] - 48), c[S] |= 1 << j;
	for(d = 1; ; d++) if(dfs(1, 0)) return 0;
	return 0;
}

$5.3$ 签到题 题解报告

标签:lang   contain   get   mes   字符串   while   struct   情况   出现   

原文地址:https://www.cnblogs.com/blank-space-/p/14728383.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!