首页 > 其他分享 >Solution - Atcoder ARC127E Priority Queue

Solution - Atcoder ARC127E Priority Queue

时间:2024-07-12 15:19:59浏览次数:7  
标签:Atcoder 于是 int 前面 Queue Priority maxn 操作 考虑

考虑转化一下,每个最后留下来的集合都相对的对应着一个被删除的集合。
于是考虑去对被删除的数去计数。

然后贪心的,去让每一次 \(2\) 操作删除的数都是前面加入中还剩下的最后加入的数(因为有的可能被前面的 \(2\) 操作删了)。
对于证明,考虑到如果不是剩下的最后加入的,那么中间可能会有 \(2\) 操作截胡了,且把其调整到最后加入肯定不劣。

于是可以先把这些已经确定要被删去的 \(1\) 操作删掉,被这个操作一起考虑到 \(2\) 操作上。
那么此时 \(2\) 操作的定义就是把一个大于当前已有的数的集合的没选过的数加入到删除的集合里。

于是可以知道对于一个 \(2\) 操作,其选的数一定会大于前面每个 \(1\) 操作选的数。
但是此时 \(2\) 操作之间的大小关系还没确定,还是不是很好做。

但是,凭直觉去想一想,可以知道同样可以贪心的,让后面的 \(2\) 选的数大于前面的 \(2\) 选的数。
证明考虑记第 \(i\) 次 \(2\) 操作选到的数为 \(s_i\),那么如果有 \(i < j, s_i > s_j\),那么肯定 \(j\) 之前选的 \(1\) 都没有 \(s_j\) 大,因为 \(i < j\) 于是让 \(i\) 位置选 \(s_j\) 肯定满足,因为又有 \(s_i > s_j\) 所以 \(j\) 位置选 \(s_i\) 肯定也满足。

于是可以知道 \(2\) 操作选的数需要大于所有前面操作选的数。
记第 \(i\) 次 \(2\) 操作在操作序列中是第 \(l_i\) 个,所以可以知道这次操作选的数的区间就是 \([l_i, a]\)。

同时又有 \(2\) 操作选的数是递增的,于是考虑 DP
设 \(f_{i, j}\) 为第 \(i\) 此 \(2\) 操作选的数为 \(j\) 的方案数,那么有转移 \(f_{i, j} = \begin{cases} 0 & j < l_i\\ \sum\limits_{k = 0}^{j - 1} f_{i - 1, k} & j \ge l_i\end{cases}\)。
然后用个前缀和优化就可以了。

时间复杂度 \(\mathcal{O}(ab)\)。

#include<bits/stdc++.h>
constexpr int mod = 998244353;
const int maxn = 1e4 + 10;
int x[maxn], l[maxn];
int f[maxn];
int main() {
   int a, b;
   scanf("%d%d", &a, &b);
   for (int i = 1; i <= a + b; i++)
      scanf("%d", &x[i]);
   for (int i = a + b, tot = 0; i; i--) {
      if (x[i] == 2) tot++;
      else if (tot) x[i] = 0, tot--;
   }
   for (int i = 1, tot = 0, n = 0; i <= a + b; i++) {
      tot += x[i] > 0;
      if (x[i] == 2) l[++n] = tot;
   }
   for (int i = 0; i <= a; i++)
      f[i] = 1;
   for (int i = 1; i <= b; i++) {
      for (int j = a; j >= l[i]; j--)
         f[j] = f[j - 1];
      for (int j = l[i] - 1; ~ j; j--)
         f[j] = 0;
      for (int j = 1; j <= a; j++)
         (f[j] += f[j - 1]) %= mod;
   }
   printf("%d\n", f[a]);
   return 0;
}

标签:Atcoder,于是,int,前面,Queue,Priority,maxn,操作,考虑
From: https://www.cnblogs.com/rizynvu/p/18298459

相关文章

  • 【atcoder】习题——位元枚举
    题意:求i&M的popcount的和,i属于0……N主要思路还是变加为乘。举个例子N=22,即10110假设M的第3位是1,分析N中:00110001110010000101发现其实等价于0010001100000001也就是左边第4位和第5位不变,右边第1位和第2位不变拼接起来,相当于0000~001101110011110110001101......
  • Solution - Atcoder ABC177F I hate Shortest Path Problem
    考虑按题目所述的进行DP。设计状态\(f_{i,j}\)代表强制要求\((i,j)\)要走向\((i+1,j)\)最小的横坐标之差,这是因为对应的纵坐标之差是确定的。对于转移,考虑到对于\(j\not\in[a_i,b_i]\),直接从上面转移下来即可,即\(f_{i,j}\leftarrowf_{i-1,j}\)。对于\(j......
  • Solution - Atcoder ARC150D Removing Gacha
    考虑到每次操作都比定会选上一个点,于是答案可以表示为每个点被选中的次数之和。即令\(c_i\)为\(i\)点被选中的次数,答案即为\(E(\sum\limits_{i=1}^nc_i)\)。根据期望的线性性,考虑把答案的\(E\)拆到每个\(c_i\)上,即变为\(\sum\limits_{i=1}^nE(c_i)\)的形式。......
  • mormot.core.threads--TSynQueue
    mormot.core.threads--TSynQueue以下是对mormot.core.threads中部分代码的翻译,特别是关于TSynQueue类的部分:const//在这里定义以避免在uses子句中显式链接到syncobjs单元wrSignaled=syncobjs.wrSignaled;//等待结果:已发出信号wrTimeout=syncobjs.wrTimeout;......
  • Denso Create Programming Contest 2024(AtCoder Beginner Contest 361)E-F
    E求一条树上的路径,使得走遍整棵树花费最小。我们容易发现树上的某条简单路径只需走一次,除此之外所有的路径都需要走两次,那么显而易见,我们需要求树的直径,之后将剩余的路径权值和乘二加上直径权值就可以。F数学题,对于数学题而言,个人感觉时间复杂度的计算对于题目的求解非常重......
  • AtCoder Beginner Contest 361
    AtCoderBeginnerContest361A-Insert给定一个长度为\(N\)的序列\(A\),现在希望将数字\(X\)插入到序列的第\(K\)个数字后面,变成一个新的序列\(B\)。输出序列\(B\)。\(K,N,A_i,X\le100\)模拟题。先读入\(N,K,X\)。接着在读入\(A\)的过程中一遍读入一遍输出,如果读到了第\(K......
  • AtCoder Beginner Contest 361)
    推荐个C++编程仓库模板https://github.com/yxc-s/programming-templateA-Insertvoidsolve(){ intn,k,x; cin>>n>>k>>x; vector<int>a(n); for(auto&x:a){ cin>>x; } a.insert(a.begin()+k,x); for(inti=0;......
  • Denso Create Programming Contest 2024(AtCoder Beginner Contest 361)
    DensoCreateProgrammingContest2024(AtCoderBeginnerContest361)\(A\)Insert\(AC\)循环结构。点击查看代码inta[200];intmain(){intn,k,x,i;cin>>n>>k>>x;for(i=1;i<=n;i++){cin>>a[i];cout......
  • AtCoder Beginner Contest 361 补题记录(A~F)
    开题顺序:A-C-F-D-B-E。A直接模拟即可。boolbegmem;#include<bits/stdc++.h>#defineintlonglongusingnamespacestd;classFastIO{public:intread(){into=1,x;charch;while(!isdigit(ch=getchar())){if......
  • Solution - Atcoder ARC125E Snack
    观察到这种都是数量上限的限制,且求\(\max\)。所以可以考虑网络流建模,而流量就对应着给的糖果数。令\(S\)为源点,\(T\)为汇点,编号为\(1\simn\)的点对应的糖果的种类,编号为\(n+1\simn+m\)的点对应的小孩。连边\((S,i,a_i)\),表示第\(i\)种糖果数不超过\(a_i\)......