Technocup 2022 - Elimination Round 2 (CF1584)

D

Description

交互题。

有一个长度为\(n\)的数列\(a_i=i\),选择\(i,j,k\)\(1\le i < j < k \le n, i+1<j\)),将数列的\([i,j]\)\([j+1,k]\)翻转,得到一个新的序列。

现提供一种询问\([i,j]\),可以知道新序列\([i,j]\)中的逆序对个数。你需要通过至多40次询问猜出\(i,j,k\)的大小。

\(n\le 10^9\)

Solution

首先询问总共有多少个逆序对,然后通过\(\log_2 n\)次询问\([mid, n]\)二分找到\(i\)的位置,然后询问\([i+1,n]\),通过总逆序对数量和\([i+1,n]\)的结果可推得\(j,k\)

E

Description

给定一个数列\(\{s_i\}\),每次可以选择相邻两个数同时减去1,如果到0就不能再减了,如果可以通过一系列操作将序列元素全部变成0,我们称其winning。

给定序列\(\{a_i\}\),问其有多少个区间是winning的。

\(n\le 3\times 10^5\)

Solution

首先我们可以\(O(n)\)扫一遍判断一个序列是否winning:第一个数肯定要和第二个数一起减,第二个数的剩下部分肯定要和第三部分一起减……直到减最后一个数的时候刚好变成0,即满足条件。

我们用式子表示一下每个条件,即:

  • \(a_2-a_1\ge 0\)
  • \(a_3 - (a_2 - a_1)\ge 0\)
  • \(a_4 - [a_3 - (a_2 - a_1)]\ge 0\)
  • ……
  • \(a_{n-1} - a_{n-2} + a_{n-3}\dots \ge 0\)
  • \(a_n - a_{n-1}+a_{n-2}\dots \color{red}{=}\color{black}0\)

我们从前往后扫,将以每个数为开头的\(\sum a_i \times (-1)^i\)存在std::set里,每加入一个新的元素,通过记一个tag来修改全局的set值,每次在set中删去不满足\(\sum a_i\times (-1)^i\) \(\ge\)\(\le 0\)的,然后统计等于0的值的个数即可。

posted @ 2022-05-08 14:04  Hany01  阅读(56)  评论(0)    收藏  举报