首页 > 其他分享 >20240925 随机训练

20240925 随机训练

时间:2024-09-28 17:34:12浏览次数:1  
标签:cnt const string 训练 int top 20240925 随机 using

Link

Update Max

将总贡献拆成每个位置单独的贡献。

假设一共有 \(m\) 个数未确定。

如果 \(a_i \neq -1\),那么产生贡献的条件就是:

  • 前面每个 \(a_j < a_i\)。
  • 前面填充的 \(cnt\) 个空的数都要小于 \(a_i\)。

第一个条件可以直接判断,第二个考虑使用组合数学。由于只能使用那些小于 \(a_i\) 的数,假设一共有 \(x\) 个,那么答案就是 \(A_x^{cnt}\)。而后面的空都可以任意填充,那么贡献还需要乘 \((m-cnt)!\)。总贡献:\(A_x^{cnt} \times (m-cnt)!\)。

如果 \(a_i = -1\),那么条件可以拆成:

  • \(cnt\) 个空(包括自己)中,最大值要大于 \(\max\limits_{1\leqslant j < i} a_j\).
  • \(cnt\) 个空中,位于 \(i\) 的空数字最大。

第一个条件似乎不太好求,考虑正难则反,用总情况数(\(A_m^{cnt}\))减去每个数都小于的情况(假设有 \(x\) 个数不合法,那么就是 \(A_x^{cnt}\))。

对于第二个条件,由于最大值在每个位置的情况都是相同的,将贡献除以 \(cnt\) 即可。同上,后面的空可以任意填充,贡献还需要乘 \((m-cnt)!\)。

总贡献:\(\frac{(A_m^{cnt}-A_x^{cnt})\times (m-cnt)!}{cnt}\)。

点击查看代码
#include <bits/stdc++.h>
#define _1 (__int128)1

using namespace std;
using ll = long long;

void FileIO (const string s) {
  freopen(string(s + ".in").c_str(), "r", stdin);
  freopen(string(s + ".out").c_str(), "w", stdout);
}

const int N = 2e5 + 10, mod = 998244353;

int n, a[N], b[N], m, inv[N], X[N], F[N], ans, mx[N], cnt;
bool f[N];

inline int C (int a, int b) {
  return (a >= b ? 1ll * F[a] * X[b] % mod * X[a - b] % mod : 0);
}

inline int A (int a, int b) {
  return (a >= b ? 1ll * F[a] * X[a - b] % mod : 0);
}

int qmod (int x, int y) {
  int ret = 1;
  while (y) ret = (y & 1 ? 1ll * ret * x % mod : ret), x = 1ll * x * x % mod, y >>= 1;
  return ret;
}

signed main () {
  ios::sync_with_stdio(0), cin.tie(0);
  // FileIO("");
  cin >> n;
  inv[1] = X[0] = F[0] = 1;
  for (int i = 2; i <= n; i++)
    inv[i] = 1ll * (mod - mod / i) * inv[mod % i] % mod;
  for (int i = 1; i <= n; i++)
    X[i] = 1ll * X[i - 1] * inv[i] % mod, F[i] = 1ll * F[i - 1] * i % mod;
  for (int i = 1; i <= n; i++)
    cin >> a[i], f[(a[i] != -1 ? a[i] : 0)] = 1, mx[i] = max(a[i], mx[i - 1]);
  for (int i = 1; i <= n; i++)
    if (!f[i])
      b[++m] = i;
  for (int i = 1; i <= n; i++) {
    if (a[i] == -1) {
      cnt++, ans = (ans + 1ll * (A(m, cnt) - A((lower_bound(b + 1, b + m + 1, mx[i]) - b - 1), cnt)) * A(m - cnt, m - cnt) % mod * qmod(cnt, mod - 2)) % mod;
    } else if (a[i] > mx[i - 1]) {
      ans = (ans + 1ll * A((lower_bound(b + 1, b + m + 1, a[i]) - b - 1), cnt) * A(m - cnt, m - cnt)) % mod;
    }
  }
  cout << ans;
  return 0;
}

Taffy Permutation

令 \(dp_{i,j}\) 表示考虑前 \(i\) 个数,\(s_i=1\) 的位置还有几种选择的情况下一共有多少种合法数组。

  • 如果 \(s_i = 1\),则 \(dp_{i-1,j+1} \xrightarrow{\times (j+1)} dp_{i,j}\)。
  • 如果 \(s_i = 0\),则大致分成两种情况:
    • 选择的数字不改变 \(j\),则有 \(n-i-j+1\) 种选法。
    • 选择的数字改变 \(j\),则 \(\sum\limits_{j+1\leqslant k \leqslant n} dp_{i-1,k} \rightarrow dp_{i,j}\)。
点击查看代码
#include <bits/stdc++.h>
#define _1 (__int128)1

using namespace std;
using ll = long long;

void FileIO (const string s) {
  freopen(string(s + ".in").c_str(), "r", stdin);
  freopen(string(s + ".out").c_str(), "w", stdout);
}

const int N = 2010, mod = 998244353;

int n, dp[N][N], sum[N][N];
string s;

signed main () {
  ios::sync_with_stdio(0), cin.tie(0);
  // FileIO("");
  cin >> n >> s, s = " " + s, dp[0][n] = 1;
  for (int i = 1; i <= n; i++) sum[0][i] = 1;
  for (int i = 1; i <= n; i++) {
    for (int j = 0; j <= n; j++) {
      if (s[i] == '0')
        dp[i][j] = (1ll * dp[i - 1][j] * (n - i - j + 1) + sum[i - 1][j + 1]) % mod;
      else
        dp[i][j] = 1ll * (j + 1) * dp[i - 1][j + 1] % mod;
    }
    for (int j = n; j; j--) sum[i][j] = (sum[i][j + 1] + dp[i][j]) % mod;
  }
  cout << dp[n][0];
  return 0;
}

Star Divine

注意要处理重边。

有两种做法:随机化和贪心。

随机化:顾名思义,就是随机每个红色星星是否选择,接着判断将每个可选的蓝色星星都选上后星星个数是否足够。

点击查看代码
#include <bits/stdc++.h>
#define _1 (__int128)1

using namespace std;
using ll = long long;

void FileIO (const string s) {
  freopen(string(s + ".in").c_str(), "r", stdin);
  freopen(string(s + ".out").c_str(), "w", stdout);
}

const int N = 1e5 + 10;

int T, n, m, ed, stk[N], top, stk_[N], top_, ans;
set<int> g[N];
bool f[N];

void Solve () {
  mt19937 rnd(time(0));
  cin >> n >> m >> ed;
  for (int i = 1; i <= n; i++) g[i] = set<int> ();
  for (int i = 1, x, y; i <= ed; i++)
    cin >> x >> y, g[x].insert(y);
  while (1) {
    top = top_ = 0;
    for (int i = 1; i <= m; i++) {
      f[i] = rnd() % 2;
      if (f[i])
        stk_[++top_] = i;
    }
    for (int i = 1; i <= n; i++) {
      bool cnt = 0;
      for (int j : g[i])
        cnt ^= f[j];
      if (cnt)
        stk[++top] = i;
    }
    if (top + top_ < (n + m + 1) / 2) continue;
    cout << top << ' ' << top_ << '\n';
    for (int i = 1; i <= top; i++)
      cout << stk[i] << ' ';
    cout << '\n';
    for (int i = 1; i <= top_; i++)
      cout << stk_[i] << ' ';
    return ;
  }
}

signed main () {
  ios::sync_with_stdio(0), cin.tie(0);
  // FileIO("");
  for (cin >> T; T--; Solve(), cout << '\n') {}
  return 0;
}

贪心:按照顺序去看每个红色星星是选择还是不选择好,即看做完前 \(i - 1\) 颗红星星的决策后,选择第 \(i\) 颗红星星可以使得哪些蓝星星必然可以选择,而不选择第 \(i\) 颗红星星又可以使得哪些蓝星星必然可以选择,选择两种情况中较大的。容易发现这样必然每次选的星星数量都至少是它可以决定的星星数量的一半,所以可以满足要求。

点击查看代码
#include <bits/stdc++.h>
#define _1 (__int128)1

using namespace std;
using ll = long long;

void FileIO (const string s) {
  freopen(string(s + ".in").c_str(), "r", stdin);
  freopen(string(s + ".out").c_str(), "w", stdout);
}

const int N = 1e5 + 10;

int T, n, m, ed, stk[N], top, stk_[N], top_, ans, lst[N];
set<int> g[N];
bool f[N];

void Solve () {
  cin >> n >> m >> ed, top = top_ = 0;
  for (int i = 1; i <= m; i++) g[i] = set<int> ();
  for (int i = 1; i <= n; i++) f[i] = 0, lst[i] = 0;
  for (int i = 1, x, y; i <= ed; i++)
    cin >> x >> y, g[y].insert(x), lst[x] = max(lst[x], y);
  for (int i = 1; i <= m; i++) {
    int cnt = 1, cnt_ = 0;
    for (int j : g[i])
      if (i == lst[j])
        cnt += !f[j], cnt_ += f[j];
    if (cnt > cnt_) {
      stk[++top] = i;
      for (int j : g[i]) f[j] ^= 1;
    }
  }
  for (int i = 1; i <= n; i++)
    if (f[i])
      stk_[++top_] = i;
  cout << top_ << ' ' << top << '\n';
  for (int i = 1; i <= top_; i++)
    cout << stk_[i] << ' ';
  cout << '\n';
  for (int i = 1; i <= top; i++)
    cout << stk[i] << ' ';
}

signed main () {
  ios::sync_with_stdio(0), cin.tie(0);
  // FileIO("");
  for (cin >> T; T--; Solve(), cout << '\n') {}
  return 0;
}

标签:cnt,const,string,训练,int,top,20240925,随机,using
From: https://www.cnblogs.com/wnsyou-blog/p/18433129/plb-20240925

相关文章

  • 算法训练营第三天| 203.移除链表元素、707.设计链表、206.反转链表
    203.移除链表元素状态:完成个人思路:首先令head符合条件,之后判断这个head是否为空,空的话返回空节点;非空的话继续进行。令pre=head;cur=head->next,只要cur非空,就判断cur的值的情况,如果需要删除,就改变pre->next和cur;如果不需要删除就继续检查下一个。看完讲解视频之后的想法:我......
  • 算法训练营第二天| 209.长度最小的子数组、59.螺旋矩阵II
    209.长度最小的子数组状态:没写出来->确认自己的想法是对的之后写出来了!!!初始思路:因为子数组是连续的,所以可以采用滑动窗口,我把这个窗口设置为左闭右闭,所以初始左右边界为0。之后先移动右指针,使得找到第一个和大于等于target的子数组,记录其长度,之后再移动左指针一位,再找第二个......
  • [题目记录]一本通高手训练-01背包
    题意有\(n\)个物品,每个物品体积为\(s_i\),价值为\(v_i\),求背包容量为\(1,2,\cdotsm\)时最大价值.\(n\le1e6,m\le1e5,s\le300,v\le1e9\)时空限制\(5s,512MB\)题解普通01背包复杂度\(O(nm)\),无法满足\(n\le1e6,m\le1e5\).发现\(s\le300\),可以考虑......
  • 随机森林(Random Forest)实现足球大小球数据分析推荐思路
    前言随机森林(RandomForest)是一种集成学习方法,它通过构建多个决策树并将它们的预测结果进行汇总来提高预测的准确性和稳定性。在足球比赛的大小球预测中,大小球通常指的是一场比赛中进球总数的预测,比如是否超过或低于某个特定的阈值(如2.5球)。下面是如何使用随机森林来实现足球......
  • 代码随想录算法训练营第三天 | 熟悉链表
    链表的存储方式数组是在内存中是连续分布的,但是链表在内存中可不是连续分布的。链表是通过指针域的指针链接在内存中各个节点。所以链表中的节点在内存中不是连续分布的,而是散乱分布在内存中的某地址上,分配机制取决于操作系统的内存管理。链表的定义template<typenameT>......
  • Stable Diffusion绘画 | 来训练属于自己的模型:秋叶训练器使用(附模型训练器)
    下载安装LoRA模型训练一键包需要安装包的小伙伴直接扫码可获取第1步:安装包下载解压后,先运行A强制更新-国内加速.bat:它会自动安装一系列的必须部件。第2步:安装完毕之后,点击运行A启动脚本.bat,打开秋叶训练器:素材准备由于秋叶训练器内没有repeat值的设置,......
  • 使用cifar100上训练的resnet18进行ood测试
    以cifar100作为闭集(closed-set)数据集,使用resnet18模型进行训练,然后在常见的开集(out-of-distribution)数据集上进行OOD检测。使用MSP(MaximumSoftmaxProbability)作为OOD检测的依据。开集噪声数据集使用gaussian,rademacher,blob,svhn四种类型。其中gaussian、rademacher......
  • 代码随想录算法训练营第二天| 209.长度最小的子数组、59.螺旋矩阵II 、区间和、开发
    209.长度最小的子数组此题注重理解,同时我将res一开始初始化为sums的长度加一(因为不可能为此长度)INT32_MAX是一个常量,代表32位有符号整数的最大值classSolution{public:intminSubArrayLen(inttarget,vector<int>&nums){inti=0,j=0;//i为起始位置,j为......
  • 【2024.09.27】NOIP2024 赛前集训-刷题训练(3)
    【2024.09.27】NOIP2024赛前集训-刷题训练(3)「NOIP2018提高组」铺设道路算法一:模拟正常人铺路的过程,每次找区间的最小值,最小值就是本次填的高度,由于出现了若干个0位置,就分裂成若干个子区间去重复上述过程,直到全部变成0。时间复杂度\(O(nlogn)\),瓶颈在预处理st表。算法二:若......
  • 【C语言训练题库】第一次出现的字符
     ......