2024/09/23 模拟赛总结

rk3,0+100+30+5=135

#A. 依依寺

唐氏分类讨论,赛时写了个记搜爆0了

因为 0 不会改变取得数的和,所以 a 可以改为 amod2

接下来分类讨论

  • 假设先手取 1,那么后手取 2 直接输,则一定先取 1,接下来先手取 1 又输,只能取 2,然后就会循环后手 1,先手 2,后手 1,先手 2

  • 假设先手取 2,同理接下来会循环后手 2,先手 1,后手 2,先手 1

0 可以交换先后手,再进行一次分讨即可

// BLuemoon_
#include <bits/stdc++.h>

using namespace std;
using LL = long long;

int t;
LL a, b, c;

void pr(bool pr) {
  cout << (pr ? "Second" : "First") << '\n';
}

int main() {
  ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
  freopen("yiyi.in", "r", stdin);
  freopen("yiyi.out", "w", stdout);
  for (cin >> t; t; t--) {
    cin >> a >> b >> c;
    (a & 1) ? (pr(b ? (b - 1 <= c && c <= b + 1) : (c == 0 || c == 1))) : (pr(b == 1 ? 0 : (b ? c == 0 : c != 1)));
  }
  return 0;
}

#B. 武义寺

赛时用了 1h 把式子推出来了,跑了 104 组拍子,没挂分

考虑打表找规律,令 vival(p)=i 的方案数,显然不论如何放 val 一定不等于 1,表格中不存在即没有限制。

i=2 时:

p2
1

答案为 (n1)!

i=3 时:

p2 方案数 p3
n1(除去1) 1
n2(除去1,p3) 2

答案为 [(n1)+(n2)](n2)!

i=4 时:

p2 方案数 p3 方案数 p4
n2(除去1,p3) n2(除去1,2) 1
n3(除去1,p3,p4) n2(除去1,2) 2
n3(除去1,p3,p4) n3(除去1,2,p4) 3

答案为 [(n2)2+(n2)(n3)+(n3)2](n3)!

i=5 时:

p2 方案数 p3 方案数 p4 方案数 p5
n3(除去1,p3,p4) n3(除去1,2,p4) n3(除去1,2,3) 1
n4(除去1,p3,p4,p5) n3(除去1,2,p4) n3(除去1,2,3) 2
n4(除去1,p3,p4,p5) n4(除去1,2,p4,p5) n3(除去1,2,3) 3
n4(除去1,p3,p4,p5) n4(除去1,2,p4,p5) n4(除去1,2,3,p5) 4

答案为 [(n3)3+(n3)2(n4)+(n3)(n4)2+(n4)3](n4)!

到这里已经大概看出规律了,ni+2,ni+1 形成了一个阶梯。

这样就可以列出式子:vi=j=0i2(ni+1)j(ni+2)ij2

但是这样还是 O(n2) 的做法,考虑 (ni+1)+1=ni+2,令 a=ni+1

证明 i=0kai(a+1)ki=(a+1)k+1ak+1

这是一个不严谨的证明,因为我们再次使用了找规律
考虑当 k=5 时,我们展开和式:
a5+5a4+10a3+10a2+5a+1
+a5+4a4+6a3+4a2+a
+a5+3a4+3a3+1a2
+a5+2a4+a3
+a5+a4
+a5
按列相加得到 6a5+15a4+20a3+15a2+6a+1,通过补项得到:a6+6a5+15a4+20a3+15a2+6a+1a6=(a+1)6a6

Q.E.D.

直接按式子模拟即可,注意 k=i2,由于是期望,最后要除掉 in!

// BLuemoon_
#include <bits/stdc++.h>

using namespace std;
using LL = long long;

const LL kP = 998244353;
const int kMaxN = 1e6 + 5;

LL n, f[kMaxN], ans, cnt;

LL P(LL x, LL y, LL ret = 1) {
  for (; y; (y & 1) && ((ret *= x) %= kP), (x *= x) %= kP, y >>= 1) {
  }
  return ret;
}

int main() {
  ios::sync_with_stdio(0), cin.tie(0), cout.tie(0), f[0] = 1;
  freopen("wuyi.in", "r", stdin);
  freopen("wuyi.out", "w", stdout);
  for (int i = 1; i < kMaxN; i++) {
    f[i] = f[i - 1] * i % kP;
  }
  cin >> n;
  for (LL i = 2, tmp = 0; i <= n + 1; i++, tmp = 0) {
    cnt = f[n - i + 1] * i % kP; 
    LL l = n - i + 1;
    tmp = (P(l + 1, i - 1) - P(l, i - 1)) % kP, (tmp += kP) %= kP;
    (cnt *= tmp) %= kP;
    (ans += (cnt * P(f[n], kP - 2) % kP)) %= kP;
  }
  cout << ans << '\n';
  return 0;
}

#C. 依久依久

考虑前缀和,则 ans=SrSl1

可以使用递归求解,令 k 为最大的 k 满足 fibknSn=Sfibk1Snfibk([(nfibk)mod2=0]×fibk)

还可以顺便记忆化一下,降低复杂度

// BLuemoon_
#include <bits/stdc++.h>

using namespace std;
using LL = long long;

const int kMaxN = 1e7 + 5;

int t;
LL l, r, f[kMaxN];
unordered_map<LL, LL> mp;

LL S(LL x, LL ret = 0) {
  if (x <= 0) {
    return 0;
  }
  if (mp.count(x)) {
    return mp[x];
  }
  for (int i = 88; i; i--) {
    if (x >= f[i]) {
      if (x - f[i] % 2 == 0) {
        ret ^= f[i];
      }
      return mp[x] = ret ^ S(x - f[i]) ^ S(f[i] - 1);
    }
  }
  return 0;
}

int main() {
  ios::sync_with_stdio(0), cin.tie(0), cout.tie(0), f[1] = 1, f[2] = 2;
  freopen("yijiu.in", "r", stdin);
  freopen("yijiu.out", "w", stdout);
  for (int i = 3; i <= 88; i++) {
    f[i] = f[i - 1] + f[i - 2];
  }
  for (cin >> t; t; t--) {
    cin >> l >> r, cout << (S(r) ^ S(l - 1)) << '\n';
  }
  return 0;
}

#D. 补幺梨

比较板子的同余最短路,模数为 min{ai,m},答案为 min{disik}

// BLuemoon_
#include <bits/stdc++.h>

using namespace std;
using LL = long long;

const int kMaxN = 1e7 + 5, kMaxM = 3e7 + 5;

int t, n, m, a[kMaxN];
LL dis[kMaxM], ans = -1;
priority_queue<pair<LL, LL>, vector<pair<LL, LL>>, greater<pair<LL, LL>>> q;

int main() {
  ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
  freopen("pear.in", "r", stdin);
  freopen("pear.out", "w", stdout);
  cin >> n >> m;
  for (int i = 1; i <= n; i++) {
    cin >> a[i], m = min(m, a[i]);
  }
  fill(dis, dis + m, 1e18);
  for (q.push({0, 0}), dis[0] = 0; !q.empty();) {
    auto [w, v] = q.top();
    q.pop();
    if (dis[v] != w) {
      continue;
    }
    for (int i = 1; i <= n; i++) {
      if (dis[(v + a[i]) % m] > dis[v] + a[i]) {
        dis[(v + a[i]) % m] = dis[v] + a[i], q.push({dis[(v + a[i]) % m], (v + a[i]) % m});
      }
    }
  }
  for (int i = 0; i < m; i++) {
    ans = max(ans, dis[i] - m);
  }
  cout << ans << '\n';
  return 0;
}
posted @   BluemoonQwQ  阅读(21)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示