3/8 训练笔记

闲话

排查许久后发现:
int vis[20000010] -> ac
long long vis[20000010] -> mle
并且开了 dill 所以查了挺久。

一个诡异的 bug 是:
...; debug(f, g) -> ac
...; -> wa
最后发现 vector resize 小了。
并且不知道为什么 debug 一下就好了。

P3702 [SDOI2017] 序列计数 题解

考虑设 \(f(x)\) 为一个多项式,其中 \(x^i\) 的系数表示有多少个长度为 \(x\) 的序列 \(a\),满足 \(\Sigma_{j = 1}^x a_j \equiv \pmod p\)
那么我们初始化 \(f(x)\) 为系数全为1的多项式,\(g(x)\) 为当 \(i\) 不为质数时系数为1,否则为0的多项式。
我们考虑求出 \(f^n(x)\)\(g^n(x)\),容易发现 \(f^n(0) - g^n(0)\) 即为答案。
时间复杂度:\(O(m + p^2logn)\)
代码:

#include <iostream>
#include <vector>
#include <map>
#ifndef ONLINE_JUDGE
#include "../../../debug.hpp"
#else
#define debug(...)
#define debugArr(...)
#endif 
#define int long long
using namespace std;
const int mod = 20170408;
signed vis[20000010],n,m,p;
vector<int> prime;
vector<int> v;
vector<int> res;
vector<int> f,g;
vector<int> mul(vector<int> &v1, vector<int> &v2) {
	for (int i = 0; i < p; i++) {
		v[i] = 0;
	}
	// cout << "v : ";
	// for (auto i:v) {
	// 	cout << i << " ";
	// }
	// cout << "\n";
	// cout << "v1 : ";
	// for (auto i:v1) {
	// 	cout << i << " ";
	// }
	// cout << "\n";
	// cout << "v2 : ";
	// for (auto i:v2) {
	// 	cout << i << " ";
	// }
	// cout << "\n";
	for (int i = 0; i < p; i++) {
		for (int j = 0; j < p; j++) {
			v[(i + j) % p] += v1[i] * v2[j] % mod;
			v[(i + j) % p] %= mod;
		}
	}
	// debug(v);
	// cout << "v : ";
	// for (auto i:v) {
	// 	cout << i << " ";
	// }
	// cout << "\n";
	return v;
}
vector<int> qpow(vector<int> &b, int k) {
	k--;
	res = b;
	while (k) {
		// debug(res);
		if (k & 1) res = mul(res, b);
		b = mul(b, b);
		k >>= 1;
		// for (auto i:res) {
		// 	cout << i << " ";
		// }
		// cout << "\n";
	}
	// for (auto i:res) {
	// 	cout << i << " ";
	// }
	// cout << "\n";
	return res;
}
void findPrime() {
	vis[1] = 1;
	for (int i = 2; i <= m; i++) {
		if (!vis[i]) prime.push_back(i);
		for (int j = 0; j < prime.size() && i * prime[j] <= m; j++) {
			vis[i * prime[j]] = 1;
		}
	}
}
signed main()
{
	cin >> n >> m >> p;
	// m = min(m, (long long)1e7);
	findPrime();
	// debug(prime);
	f.resize(p + 1, 0);
	g.resize(p + 1, 0);
	v.resize(p + 1, 0);
	for (int i = 1; i <= m; i++) {
		// debug(i);
		f[i % p]++;
		if (vis[i]) g[i % p]++;
	}

	// for (int i = 1; i <= m; i++) {
	// 	cout << f[i] << "\n";
	// }

	// debug()


	f = qpow(f, n);
	// for (auto i:qpow(f, n)) {
	// 	cout << i << " ";
	// }
	// cout << "\n";
	g = qpow(g, n);
	// debug(f, g);
	cout << (f[0] - g[0] + mod) % mod << "\n";
}
posted @ 2024-03-08 20:29  IANYEYZ  阅读(2)  评论(0编辑  收藏  举报