2026.7.6考试总结
省流:100 + 0 + 30 + 0
T1 walk
题目大意就是有 \(n\) 盏灯,每盏灯循环亮不同颜色,问 \([l,r]\) 时间内有多少秒所有灯颜色一样。
开场就一直在想如何转化,发现机房已经有大佬开始敲了有点慌,然后突然发现只有 \(2 \times 10^5\) 种颜色,一下子就会了。
我们注意到对于每种颜色显然是以下的形式:
其中 \(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\)。再代入题目的通项公式得到,我们需要求
利用组合恒等式:
于是:
令 \(j=i+1\),则 \(j\) 从 \(1\) 到 \(m+1\),得到最终式子:
由 Lucas 定理,设:
则有
其中 \(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\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}\)。
于是得到递归式:
其中 \(T(r,t) = \sum_{b=0}^{t}\binom{r}{b}\),而 \(0\le r,t < p\),可以直接计算。
T4 challenge


浙公网安备 33010602011771号