首页 > 其他分享 >[AGC056B] Range Argmax

[AGC056B] Range Argmax

时间:2024-10-04 08:50:11浏览次数:8  
标签:Argmax rep pos len int Range AGC056B 区间 define

发现一个序列 \(x\) 不止可以用一个 \(p\) 得到,肯定不能直接计数,考虑构造一个映射。

假如已经定下了 \(x\),我们通过一种固定的操作得到 \(p\),这样就能改为统计可以由操作得到的 \(p\) 的数量,他们同样唯一对应一个 \(x\)。

我们考虑枚举从 \(n\) 到 \(1\) 去枚举 \(v\),对每个 \(v\) 找到一个能找到的最左边的点赋值。一个位置 \(pos\) 能赋值 \(v\) 当且仅当所有 \(l_i,r_i\) 包含 \(pos\) 的 \(x_i\) 等于 \(pos\)。

接下来我们就可以处理左区间和右区间的位置了。容易发现其右边的值都要小于左边的值,这将变成两个子问题。

现在 \(x\) 并不固定,我们需要分析条件才能计数。

注意到,若当前我们在 \(pos\) 这里赋值,那么对于左侧的最大值的位置 \(k\),一定存在一个区间满足 \(l_i\le k\le pos\le r_i\),因为若没有区间同时包含 \(k,pos\),那么显然我可以让 \(p_{pos}=v\),所以一定存在这样的区间。之所以存在这种情况那只能是因为这个区间的 \(x_i\) 等于 \(pos\)。我们需要用一个大数在这里填,填完以后再将区间删去才能更新 \(k\)。

这启发我们进行一个区间 dp,设 \(f_{l,r,i}\) 表示在区间 \(l,r\) 中最大值位置在 \(i\) 的方案数。但是由于这样子复杂度很劣,我们将状态改为在区间 \(l,r\) 中最大值位置大于等于 \(i\) 的方案数就能 \(\mathcal{O}(n^3)\) 解决问题了,具体就是先维护区间如果要选 \(pos\) 赋值,包含 \(pos\) 的区间的最小 \(l_i\),然后再后缀和转移即可。

代码:

#include <bits/stdc++.h>
#define int long long
#define rep(i, l, r) for (int i = l; i <= r; ++ i)
#define rrp(i, l, r) for (int i = r; i >= l; -- i)
#define pii pair <int, int>
#define eb emplace_back
#define id(x, y) n * (x - 1) + y
#define ls p << 1
#define rs ls | 1
using namespace std;
constexpr int N = 300 + 5, M = (1ll << 31) - 1, P = 998244353;
constexpr double PI = acos (-1.0);
inline int rd () {
  int x = 0, f = 1;
  char ch = getchar ();
  while (! isdigit (ch)) {
    if (ch == '-') f = -1;
    ch = getchar ();
  }
  while (isdigit (ch)) {
    x = (x << 1) + (x << 3) + ch - 48;
    ch = getchar ();
  }
  return x * f;
}
int qpow (int x, int y) {
  int ret = 1;
  for (; y; y >>= 1, x = x * x % P) if (y & 1) ret = ret * x % P;
  return ret;
}
int f[N][N][N], g[N][N][N];
int n, m;
long long fac[N], ifac[N];
int C (int n, int m) {
  if (m < 0 || m > n) return 0;
  return fac[n] * ifac[m] % P * ifac[n - m] % P;
}
int l[N * N], r[N * N];
signed main () {
  // freopen ("1.in", "r", stdin);
  // freopen ("1.out", "w", stdout);
  n = rd (), m = rd ();
  rep (i, 1, m) l[i] = rd (), r[i] = rd ();
  rep (i, 0, n + 1) rep (j, 0, n + 1) rep (k, 0, n + 1) g[i][j][k] = n + 1;
  rep (i, 1, m) {
    rep (j, l[i], r[i]) {
      g[l[i]][r[i]][j] = min (g[l[i]][r[i]][j], l[i]); 
    }
  }
  rep (len, 1, n) {
    rep (l, 1, n - len + 1) {
      int r = l + len - 1;
      rep (k, 1, n) g[l][r][k] = min (g[l][r][k], min (g[l + 1][r][k], g[l][r - 1][k]));
    }
  }
  rep (l, 1, n + 1) rep (k, 1, n + 1) f[l][l - 1][k] = 1;
  rep (len, 1, n) {
    rep (l, 1, n - len + 1) {
      int r = l + len - 1;
      rrp (k, l, r) {
        (f[l][r][k] += f[l][r][k + 1] + f[l][k - 1][g[l][r][k]] * f[k + 1][r][k + 1]) %= P;
      }
    }
  } cout << f[1][n][1];
}

标签:Argmax,rep,pos,len,int,Range,AGC056B,区间,define
From: https://www.cnblogs.com/lalaouyehome/p/18446270

相关文章

  • 'Note' - 'SIGMOD24' - SeRF - Segment Graph for Range-Filtering (RF) Approximate
    Abstract:就是ANNS加了一个范围查询(每个点多个属性,每次查询一个区间),为啥不是线段树来着。他说《SegmentGraph(查前缀\(O(n)\))》《2DSegmentGraph(查区间构建\(O(n\logn)\))》2.Preliminary有太多ANNs负责优化找到的正确率??2.1问题定义\(I_A\)属性区间\(\mathcal......
  • 【VBA】UsedRangeの範囲から最終行など取得【UsedRange.Rows.Countなど】
    参考元:【VBA】UsedRangeの範囲から最終行など取得【UsedRange.Rows.Countなど】https://daitaideit.com/vba-usedrange/ポイントとなるVBAコードWithActiveSheet.UsedRange.Select'使用しているセル範囲'行.Rows(1).Select'1行目.Rows(.Rows.C......
  • 【VBA】セル範囲をセルに代入するときの注意点【RangeにValueをつける】
    参考元:【VBA】セル範囲をセルに代入するときの注意点【RangeにValueをつける】https://daitaideit.com/vba-range-value/ポイントとなるVBAコード'セル範囲を値として別セルに代入Range("E1:G3").Value=Range("A1:C3").Value'OKRange("E1:G3")=Range("A1:C3")'ダメ......
  • 【VBA】RangeやCellsの範囲を移動する【Offsetを使います】
    参考元:【VBA】RangeやCellsの範囲を移動する【Offsetを使います】https://daitaideit.com/vba-range-offset/ポイントとなるVBAコードCells(1,1).Offset(2,3).Select'Cellsを2行と3列だけ移動するRange("A1").Offset(2,3).Select'Rangeをを2行と3列だけ移動するVBA......
  • 题解 CF1785D - Range = √Sum
    link\(\texttt{Describe}\)构造有\(n\)个数的序列,满足以下条件:\(\foralli\in[1,n]\)并且\(1\lea_i\le10^9\)。对于任何的\(1\lei,j\len(i\nej)\),\(a_i\nea_j\)。\((\max_{i=1}^{n}a_i-\min_{i=1}^{n}a_i)^2=\sum_{i=1}^{n}a_i\)。......
  • WPF slider IsSelectionRangeEnabled TickFrequency
    <Windowx:Class="WpfApp426.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d="http://schemas.microsoft......
  • Orange Pi + SPI点亮 ws2812
    开发板型号:OrangePiOne系统版本:Ubuntu20.04focalDesktop接口:SPI1.连线TB上买的ws2812大概长这样:细节标在图上了。带插头的一端连上即可。其带针脚一端是多组灯带串联时候用。DI接SPI的MOSI。参考博客[1]2.启用硬件SPI在设置里有一个orangepi-config的执行程序,可......
  • 05 第六组(10个) sorted enumerate callable id len range open input
    第六组(10个)lenprintinputopen,文件rangepy2:v1=rang(10)#会生成列表[0....9]立即创建v1=xrang(10)#生成对象不会立即创建,只有使用循环时,进行创建,用一个进行创建一个,更节省内存py3:v1=rang(10)#会生成列表[0....9]#生成......
  • opencascade Bnd_Range源码学习区间计算
    opencascadeBnd_Range前言这个类描述了由两个实数值限定的1D空间中的区间。一个区间可以是无效的,这表示区间中不包含任何点。方法1默认构造函数。创建一个无效区间。Bnd_Range();2构造函数。创建最小最大值区间Bnd_Range(constStandard_RealtheMin,constStandar......
  • Python学习:range、xrange和arange的区别
    range生成左闭右开区间的整数。例子见下:np.arange生成左闭右开区间内的小数。例子见下:range和xrange有版本区别(这部分转载):Python3range()函数返回的是一个可迭代对象(类型是对象),而不是列表类型,所以打印的时候不会打印列表。Python3list()函数是对象迭代器,可以把ra......