2025-2 好题
2025-2 好题
UOJ Round 29 B - 数字生命
首先想到差分,差分后是正的就看成一些起点,负的就看成是一些终点
然后题目就相当于要对每一对起点和终点配对,然后塞一些区间覆盖进去
考虑集合幂级数,设 位第 个起点到第 个终点的可行集合,并附上随机权值,乘法是子集卷积
那么答案集合即为:
和积式不好算,不难发现乘个额外因子是没有关系的,所以考虑计算行列式:
但是子集卷积有点难算,但是可以改成或卷积,这样如果有元素或了起来,这样 就会变小,判一下即可
用 FWT 算出每个集合幂级数的点值,然后计算行列式,最后做一遍 IFWT 得到答案即可。
时间复杂度 。
ケロシの代码
const int N = 1e5 + 5;
const int M = 17;
const int P = 998244353;
inline int add(int x, int y) { return (x + y < P ? x + y : x + y - P); }
inline void Add(int & x, int y) { x = (x + y < P ? x + y : x + y - P); }
inline int sub(int x, int y) { return (x < y ? x - y + P : x - y); }
inline void Sub(int & x, int y) { x = (x < y ? x - y + P : x - y); }
inline int mul(int x, int y) { return (1ll * x * y) % P; }
inline void Mul(int & x, int y) { x = (1ll * x * y) % P; }
int fp(int x, int y) {
int res = 1;
for(; y; y >>= 1) {
if(y & 1) Mul(res, x);
Mul(x, x);
}
return res;
}
mt19937 rnd(time(0));
int n, m;
int a[N], b[N], c[N];
int st[N], ed[N], tot;
int s[1 << M];
int A[1 << M][M][M], F[1 << M];
void ADD(int x[M][M], int y[M][M]) {
REP(i, tot) REP(j, tot)
Add(x[i][j], y[i][j]);
}
void OR(int lim) {
for(int i = 1; i < lim; i <<= 1)
for(int j = 0; j < lim; j += (i << 1))
REP(k, i)
ADD(A[j + k + i], A[j + k]);
}
void IOR(int lim) {
for(int i = 1; i < lim; i <<= 1)
for(int j = 0; j < lim; j += (i << 1))
REP(k, i)
Sub(F[j + k + i], F[j + k]);
}
int det(int a[M][M], int n) {
int res = 1, w = 1;
REP(i, n) {
if(! a[i][i]) {
FOR(j, i + 1, n - 1) if(a[j][i]) {
swap(a[i], a[j]);
res = sub(0, res);
break;
}
}
if(! a[i][i]) return 0;
Mul(res, a[i][i]);
FOR(j, i + 1, n - 1) {
Mul(w, a[i][i]);
int val = a[j][i];
FOR(k, i, n - 1)
a[j][k] = sub(mul(a[i][i], a[j][k]), mul(a[i][k], val));
}
}
return mul(res, fp(w, P - 2));
}
void solve() {
cin >> n >> m;
FOR(i, 1, n) cin >> a[i];
int sum = 0;
FOR(i, 1, n) sum += a[i];
ROF(i, n + 1, 1) a[i] -= a[i - 1];
FOR(i, 1, n + 1) while(a[i] > 0) a[i] --, st[tot ++] = i;
tot = 0;
FOR(i, 1, n + 1) while(a[i] < 0) a[i] ++, ed[tot ++] = i;
if(tot > m) {
REP(_, 1 << m) cout << 0;
cout << endl;
return;
}
REP(i, m) cin >> b[i];
REP(S, 1 << m) {
REP(i, m) if(S >> i & 1) s[S] += b[i];
REP(i, tot) REP(j, tot) if(ed[j] - st[i] == s[S])
A[S][i][j] = rnd() % P;
}
OR(1 << m);
REP(S, 1 << m) F[S] = det(A[S], tot);
IOR(1 << m);
REP(S, 1 << m) cout << (sum == s[S] && F[S]);
cout << endl;
}
ブルーアーカイブ
P10063 [SNOI2024] 平方数
这题值域太大,都不能分解质因数
考虑一个平方数模一个随机大质数大概率是这个大质数的二次剩余
而在模一个大质数下,有一半的数有二次剩余,可以看作 的概率有二次剩余
所以随机 个大质数来判断,这样错误概率只有 。
接下来考虑怎么判区间是否是二次剩余,注意到判断二次剩余的方法是计算 是 还是
所以可以对于每个 单独计算 ,然后区间只要有偶数个 就是合法的,可以用 map 快速计算合法区间数量。
时间复杂度 。
ケロシの代码
const int N = 3e5 + 5;
const int V = 1e5;
const int M = 40;
int n;
int128 a[N], s[M];
ll f[N], b[N]; int len;
vector<int> e[N];
ll pri[M];
ll p[] = {2, 325, 9375, 28178, 450775, 9780504, 1795265022};
mt19937 rnd(time(0));
ll rd() {
return 1ll * (rnd() >> 3) * rnd() + rnd();
}
ll mul(ll x, ll y, ll p) {
ll k = (1.l * x * y) / (1.l * p);
ll res = x * y - k * p;
res -= p;
while(res < 0) res += p;
return res;
}
ll fp(ll x, ll y, ll p) {
ll res = 1;
for(; y; y >>= 1) {
if(y & 1) res = mul(res, x, p);
x = mul(x, x, p);
}
return res;
}
bool Miller_Rabin(ll n, ll a) {
int r = 0; ll b = n - 1;
while(! (b & 1)) b >>= 1, r ++;
ll val = fp(a, b, n);
if(val == 1) return 1;
REP(i, r) {
if(val == n - 1) return 1;
val = mul(val, val, n);
}
return 0;
}
bool ip(ll n) {
if(n < 2) return 0;
REP(i, 7) {
if(n == p[i]) return 1;
if(p[i] % n == 0) continue;
if(n % p[i] == 0) return 0;
if(! Miller_Rabin(n, p[i])) return 0;
}
return 1;
}
int128 read() {
int128 res = 0;
char c = getchar();
while(c < '0' || c > '9') c = getchar();
while('0' <= c && c <= '9') res = res * 10 + c - '0', c = getchar();
return res;
}
void init() {
REP(i, M) {
ll x = rd();
while(! ip(x)) x = rd();
pri[i] = x;
}
}
void solve() {
n = read();
FOR(i, 1, n) a[i] = read();
init();
REP(i, M) s[i] = 1;
ROF(i, n, 1) {
REP(j, M) s[j] = mul(s[j], a[i] % pri[j], pri[j]);
REP(j, M) {
ll val = fp(s[j] % pri[j], (pri[j] - 1) >> 1, pri[j]);
if(val != 1) f[i] |= 1ll << j;
}
}
FOR(i, 1, n + 1) b[++ len] = f[i];
sort(b + 1, b + len + 1);
len = unique(b + 1, b + len + 1) - b - 1;
FOR(i, 1, n + 1) f[i] = lower_bound(b + 1, b + len + 1, f[i]) - b;
ll ans = 0;
vector<PII> Ans;
ROF(i, n + 1, 1) {
ans += SZ(e[f[i]]);
e[f[i]].push_back(i);
}
FOR(i, 1, n) reverse(ALL(e[i]));
FOR(i, 1, n) {
for(int r : e[f[i]]) if(r > i) {
Ans.push_back({i, r - 1});
if(SZ(Ans) == V) break;
}
if(SZ(Ans) == V) break;
}
cout << ans << endl;
for(auto h : Ans) cout << FI(h) << " " << SE(h) << endl;
}
ブルーアーカイブ
AGC070C - No Streak
对于 Alice 的赢的次数总是要大于 Bob 的限制,不难想到反射容斥
但是不能连胜的条件相当于对折线的形态有限制,翻折后形态就会改变
考虑再容斥,设 为 Alice 胜了 局,BoB 胜了 局,有 局平局,且没有连胜,无其它限制的方案数,这个可以 求。
接下来考虑如何容斥,对到直线 的情况进行分类:
- 到 立即右转
- 到 后停歇,也就是平局
前者翻着后会有连胜,塞一个向上走进去即可,方案为 。
后者考虑塞一个停歇,就是 ,
但是不难发现如果去掉停歇后可能翻着后还有连胜,所以在塞一个向上走,为 。
所以答案就是 。
时间复杂度 。
ケロシの代码
const int N = 3e7 + 5;
const int P = 1e9 + 7;
inline int add(int x, int y) { return (x + y < P ? x + y : x + y - P); }
inline void Add(int & x, int y) { x = (x + y < P ? x + y : x + y - P); }
inline int sub(int x, int y) { return (x < y ? x - y + P : x - y); }
inline void Sub(int & x, int y) { x = (x < y ? x - y + P : x - y); }
inline int mul(int x, int y) { return (1ll * x * y) % P; }
inline void Mul(int & x, int y) { x = (1ll * x * y) % P; }
inline int mul(initializer_list<int> a) {
int res = 1;
for(int x : a) Mul(res, x);
return res;
}
int fp(int x, int y) {
int res = 1;
for(; y; y >>= 1) {
if(y & 1) Mul(res, x);
Mul(x, x);
}
return res;
}
int n, A, B, E;
int fac[N], finv[N];
void init(int n) {
fac[0] = 1;
FOR(i, 1, n) fac[i] = mul(fac[i - 1], i);
finv[n] = fp(fac[n], P - 2);
ROF(i, n - 1, 0) finv[i] = mul(finv[i + 1], i + 1);
}
int C(int x, int y) {
if(x < y || y < 0) return 0;
return mul(mul(fac[x], finv[y]), finv[x - y]);
}
int F(int A, int B, int E) {
if(! B) return C(E + 1, A);
int res = 0;
FOR(i, 1, B) {
Add(res, mul({C(B - 1, i - 1), C(A - 1, i - 2), C(E + i * 2 - 1, A + B)}));
Add(res, mul({2, C(B - 1, i - 1), C(A - 1, i - 1), C(E + i * 2, A + B)}));
Add(res, mul({C(B - 1, i - 1), C(A - 1, i), C(E + i * 2 + 1, A + B)}));
}
return res;
}
void solve() {
cin >> n >> A >> B; E = n - A - B;
init(N - 1);
int ans = F(A, B, E);
Sub(ans, F(A, B - 1, E));
Sub(ans, F(A + 1, B - 1, E - 1));
Sub(ans, F(A, B - 1, E - 1));
cout << ans << endl;
}
AGC070B - Odd Namori
首先考虑限制和权值都很奇怪,但是考虑一个容斥
设 为图 中的一个点集 ,如果 的诱导子图是由一些环构成,其中偶环有 个,那么其权值为 。
然后求 ,这样的话如果 有偶环,其权值容斥为 ,否则其权值为 , 为奇环数。
接下来考虑枚举 ,计算所有的 ,这样的话不在 里的点的方案可以直接计算。
接下来算 中的内部情况。
假设没有限制,那么可以交换两个点的出边,这样就会容斥掉,所以方案就是 。
接下来考虑有限制的情况,考虑继续容斥,减掉不合法的情况。
那么就钦定一些不合法的边
因为 的诱导子图要变成一些环,所以不存在两个点指向一个点,那么只剩下了链
注意到如果有多条链,那么可以继续容斥掉。
所以有贡献的情况一定是单链,不难发现其还要乘上后一个容斥的系数,其贡献均为 。
所以直接枚举链的长度即可。
时间复杂度 。
ケロシの代码
const int N = 1e5 + 5;
const int P = 998244353;
inline int add(int x, int y) { return (x + y < P ? x + y : x + y - P); }
inline void Add(int & x, int y) { x = (x + y < P ? x + y : x + y - P); }
inline int mul(int x, int y) { return (1ll * x * y) % P; }
inline void Mul(int & x, int y) { x = (1ll * x * y) % P; }
int fp(int x, int y) {
int res = 1;
for(; y; y >>= 1) {
if(y & 1) Mul(res, x);
Mul(x, x);
}
return res;
}
int n, p[N], d[N], s[N];
void solve() {
cin >> n;
FOR(i, 2, n) cin >> p[i];
d[1] = 1;
FOR(i, 2, n) d[i] = d[p[i]] + 1;
int ans = mul(n, fp(n - 1, n - 1));
FOR(i, 1, n) Add(ans, fp(n - 1, n - d[i]));
FOR(i, 2, n) s[d[i] - 1] ++;
ROF(i, n, 1) s[i] += s[i + 1];
FOR(i, 1, n - 1) Add(ans, mul(mul(n, s[i]), fp(n - 1, n - i - 1)));
cout << ans << endl;
}
リテラチュア
リテラチュア - 上田麗奈 (うえだ れいな)
词:RIRIKO
曲:RIRIKO
编曲:伊藤賢
彩られていけば幻想が
カタチあるものになるように
描いてゆける 叶えてゆけるんだ
優しく吹いた風が
古いページ捲るように
振り返るけど
「ううん いいのよ」
知らないことだらけの
出会い別れの話
滲むインクをそっとなぞった
どこ行くの?
少し遠くまで
置いてきたものは夢に
好きだから選ぶ
選びながら私になってゆく
「また会いましょう
約束だから」
あなたはそう微笑んだ
「また会いましょう」
小指のまじない
誰かの声がして目が覚めた
期待されていること
見向きさえされないこと
どちらが良いの?
「ううん どちらも」
嬉しいし不安だし
私だって必死だし
主人公になれていますか?
雨が降る 一つ 一つずつ
誰もいない世界みたい
満月も見ないフリしながら
明日を待っている
「信じるだけで叶えられるわ」
一人はそう 背を押した
「信じるだけで助けられるわ」
一人はそう まるで願うように
やがて青い空の上で
星は笑う
本で見たような夜だった
雨は止み 頬をつたう
朝が来た 忘れないでいてね
旅のリテラチュア
どこ行くの?
少し遠くまで
置いてきたものは夢に
好きだから選ぶ
選びながら私になってゆく
「また会いましょう
約束だから」
あなたはそう微笑んだ
「また会いましょう」
小指のまじない
誰かを信じても良いのかな
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 如何调用 DeepSeek 的自然语言处理 API 接口并集成到在线客服系统
· 【译】Visual Studio 中新的强大生产力特性
· 2025年我用 Compose 写了一个 Todo App
2021-02-24 POJ 2509 Peter's smokes(Peter的香烟)
2021-02-24 POJ题目 1003Hangover(叠放纸牌)