2026.7.6考试总结

省流:100 + 0 + 30 + 0

T1 walk

题目大意就是有 \(n\) 盏灯,每盏灯循环亮不同颜色,问 \([l,r]\) 时间内有多少秒所有灯颜色一样。

开场就一直在想如何转化,发现机房已经有大佬开始敲了有点慌,然后突然发现只有 \(2 \times 10^5\) 种颜色,一下子就会了。

我们注意到对于每种颜色显然是以下的形式:

\[\left\{\begin{matrix} x \equiv pos_1 \pmod {s_1} \\ x \equiv pos_2 \pmod {s_2} \\ \cdots \\ x \equiv pos_n \pmod {s_j} \end{matrix}\right. \]

其中 \(pos_i\) 表示颜色 \(i\) 出现的位置。显然大力 exCRT即可。

code
#include<bits/stdc++.h>
#define int long long
	using namespace std;
	const int M = 2e5 + 5;
	vector<pair<int, int>>vec[M];
	int read(){
		int sgn = 1, ans = 0;
		char c = getchar();
		while(c < '0' || c > '9'){
			if(c == '-') sgn = -sgn;
			c = getchar();
		}
		while(c >= '0' && c <= '9') ans = ans * 10 + c - '0', c = getchar();
		return sgn * ans;
	} 
	int exgcd(int a, int b, int &x, int &y) {
		if (!b) {
			x = 1, y = 0;
			return a;
		}
		int d = exgcd(b, a % b, x, y);
		int t = x;
		x = y;
		y = t - (a / b) * y;
		return d;
	}
	signed main() {
		ios::sync_with_stdio(0);
		cin.tie(0), cout.tie(0);
		freopen("walk.in", "r", stdin);
		freopen("walk.out", "w", stdout);
		int n = read(), m = read(), l = read(), r = read();
		//cin >> n >> m >> l >> r;
		for (int i = 1, s; i <= n; i++) {
			s = read();
			for (int j = 1, x; j <= s; j++) {
				x = read();
				vec[x].push_back(make_pair(s, j % s));
			}
		}
		map<pair<int, int>, int>mp;
		for (int i = 1; i <= m; i++) {
			if (vec[i].size() < n) continue;
			int a1 = vec[i].front().first, m1 = vec[i].front().second;
			for (int j = 1; j < vec[i].size(); j++) {
				int ai = vec[i][j].first, mi = vec[i][j].second;
				int k1, k2;
				int g = exgcd(a1, -ai, k1, k2);
				if ((mi - m1) % g) goto f;
				k1 = k1 * (mi - m1) / g;
				k1 = (k1 % abs(ai / g) + abs(ai / g)) % abs(ai / g);
				m1 = k1 * a1 + m1;
				a1 = abs(a1 / g * ai);
			}
			mp[make_pair(m1, a1)]++;
			f:;
		}
		int ans = 0;
		auto it = mp.begin();
		for(; it != mp.end(); it++) {
			int rr = it->first.first, mod = it->first.second, lf = l;
			int st = lf % mod;
			if(st > rr) lf += (mod - st + rr);
			else lf += rr - st;
			if(lf > r) continue;
			ans += (r - lf) / mod + 1;
		}
		cout << ans;
		return 0;
	}

T2 air

哎我真的是铸币了。

题目大概意思就是给定 \(x\)\(y\),求有多少个长度为 \(n\) 的正整数序列 \(f\),满足:\(\gcd(f_1, f_2, \cdots, f_n) = x\)\(\operatorname{lcm}(f_1, f_2, \cdots, f_n) = y\)

题目还给出了质因数分解真的是贴心到家了,显然每个质因子分开考虑,我们要让这 \(n\) 个数中:至少有一个取到最小值 \(a_i\) 且至少有一个取到最大值 \(b_i\),记 \(d_i = b_i - a_i\),用容斥原理,答案为 \((d_i + 1)^n - 2 \times (d_i)^n + (d_i - 1)^n\)。全部乘起来即可。

code
#include<bits/stdc++.h>
#define int long long
	using namespace std;
	const int M = 1e6 + 6;
	const int mod = 998244353;
	int a[M], b[M];
	int read(){
		int sgn = 1, ans = 0;
		char c = getchar();
		while(c < '0' || c > '9'){
			if(c == '-') sgn = -sgn;
			c = getchar();
		}
		while(c >= '0' && c <= '9') ans = ans * 10 + c - '0', c = getchar();
		return sgn * ans;
	} 
	int qpow(int x, int y) {
		int res = 1;
		while(y) {
			if(y & 1) res = res * x % mod;
			x = x * x % mod;
			y >>= 1;
		}
		return res;
	}
	signed main() {
		int m = read(), n = read();
		for(int i = 1; i <= m; i++) a[i] = read();
		for(int i = 1; i <= m; i++) b[i] = read();
		int res = 1;
		for(int i = 1; i <= m; i++) {
			int d = b[i] - a[i];
			if(d == 0) continue;
			int nw = (qpow(d + 1, n) + qpow(d - 1, n)) % mod;
			nw = (nw - 2 * qpow(d, n) % mod + mod) % mod;
			res = res * nw % mod;
		}
		cout << res;
		return 0;
	}

T3 dimension

首先阅读题目下发的提示可以发现 \(f_{x,y} = f_{x, y - 1} + f_{x - 1, y - 1}\),一眼发现这个就是杨辉三角,所以其实 \(f_{x,y} = \sum\limits_{i=0}^x \binom y i\)。再代入题目的通项公式得到,我们需要求

\[\sum_{y=0}^{n} f_{m,y} =\sum_{y=0}^{n}\sum_{i=0}^{m}\binom{y}{i} =\sum_{i=0}^{m}\sum_{y=0}^{n}\binom{y}{i}. \]

利用组合恒等式:

\[\sum_{y=0}^{n}\binom{y}{i} = \binom{n+1}{i+1} \]

于是:

\[\sum_{y=0}^{n} f_{m,y} =\sum_{i=0}^{m}\binom{n+1}{i+1}. \]

\(j=i+1\),则 \(j\)\(1\)\(m+1\),得到最终式子:

\[\sum_\limits{j=1}^{m+1}\binom{n+1}{j} = \sum\limits_{j=0}^{m+1}\binom{n+1}{j} - 1 \]

Lucas 定理,设:

\[n + 1 = p \cdot q + r,\quad m + 1 = p \cdot s + t,\quad 0\le r,t < p. \]

则有

\[\binom{n + 1}{k} \equiv \binom{q}{a}\binom{r}{b} \pmod p, \]

其中 \(k = p\cdot a + b,\ 0\le b<p\)

现在求和 \(k=0\)\(m + 1\),即所有满足 \(p a + b \le p s + t\)\((a,b)\)

  • \(a < s\),则 \(b\) 可以取 \(0\)\(p-1\) 任意值;
  • \(a = s\),则 \(b\) 只能取 \(0\)\(t\)

因此:

\[\sum_{k=0}^{m + 1} \binom{n + 1}{k} = \sum_{a=0}^{s-1}\sum_{b=0}^{p-1} \binom{q}{a}\binom{r}{b} + \binom{q}{s}\sum_{b=0}^{t}\binom{r}{b}. \]

第一项中,\(\sum\limits_{b=0}^{p-1}\binom{r}{b} = 2^r\)(二项式定理,模 \(p\) 下),而 \(\sum_{a=0}^{s-1}\binom{q}{a}\) 正好是 \(S(q, s-1)\),其中 \(S(X,Y) = \sum_{i=0}^{Y}\binom{X}{i}\)

于是得到递归式:

\[ S(N,M) = S(q, s-1) \cdot 2^r + \binom{q}{s} \cdot T(r,t), \]

其中 \(T(r,t) = \sum_{b=0}^{t}\binom{r}{b}\),而 \(0\le r,t < p\),可以直接计算。

T4 challenge

posted @ 2026-07-06 20:12  nick_zha  阅读(12)  评论(0)    收藏  举报