首页 > 其他分享 >[AGC061C] First Come First Serve 题解

[AGC061C] First Come First Serve 题解

时间:2024-10-08 10:22:07浏览次数:10  
标签:kMod int 题解 Serve kMaxN ret bs First

Description

有 \(n\) 个人来过,第 \(i\) 个人在 \(a_i\) 时刻来在 \(b_i\) 时刻走,每个人可以在来时或走时登记,问可能的登记顺序有多少种。

\(n\leq 5\times 10^5\),\(a_i,b_i\) 互不相同,\(\forall i<n,a_i<a_{i+1},b_{i}<b_{i+1}\)。

Solution

首先如果每个人随便选,有 \(2^n\) 种方案。但这显然会算重。考虑构造一种方案使得选的方案和最终排列一一对应。

按照排列从小到大的顺序,如果当前 \((a_i,b_i)\) 中有数,则选 \(a_i\),否则选 \(b_i\),容易发现这样做一定能够一一对应。

这时一个选择不合法当且仅当对于某个 \(i\),\((a_i,b_i)\) 中没数但 \(i\) 选了 \(b_i\),可以对不合法的位置数进行容斥。

具体的,如果选了 \(a_i\) 或 \(b_i\),则系数为 \(1\),\((a_i,b_i)\) 中没数且选 \(b_i\),则系数为 \(-1\)。

容易发现对于任意两个钦定了不合法的位置 \(i,j\),\([a_i,b_i]\) 和 \([a_j,b_j]\) 一定不相交。并且如果设 \(pre_i\) 表示最大的 \(b_j<a_i\) 的 \(j\),\(nxt_i\) 表示最小的 \(a_j>b_i\) 的 \(j\),那么如果 \(i\) 不合法,\((pre_i,i)\) 和 \((i,nxt_i)\) 选择一定是固定的。这样就可以 dp 了。

设 \(f_i\) 表示前 \(i\) 个数的系数之和。那么 \(f_i=2f_{i-1}-\sum_{nxt_j+1=i}{f_{pre_j}}\)。

时间复杂度:\(O(n)\)。

Code

#include <bits/stdc++.h>

// #define int int64_t

const int kMaxN = 5e5 + 5, kMod = 998244353;

int n;
int a[kMaxN], b[kMaxN], pre[kMaxN], nxt[kMaxN], f[kMaxN];
std::vector<int> vec[kMaxN];

constexpr int qpow(int bs, int64_t idx = kMod - 2) {
  int ret = 1;
  for (; idx; idx >>= 1, bs = (int64_t)bs * bs % kMod)
    if (idx & 1)
      ret = (int64_t)ret * bs % kMod;
  return ret;
}

inline int add(int x, int y) { return (x + y >= kMod ? x + y - kMod : x + y); }
inline int sub(int x, int y) { return (x >= y ? x - y : x - y + kMod); }
inline void inc(int &x, int y) { (x += y) >= kMod ? x -= kMod : x; }
inline void dec(int &x, int y) { (x -= y) < 0 ? x += kMod : x; }

void dickdreamer() {
  std::cin >> n;
  for (int i = 1; i <= n; ++i) std::cin >> a[i] >> b[i];
  for (int i = 1, j = 0; i <= n; ++i) {
    for (; b[j] < a[i]; ++j) {}
    pre[i] = j;
  }
  a[n + 1] = b[n + 1] = 2 * n + 1;
  for (int i = n, j = n + 1; i; --i) {
    for (; a[j] > b[i]; --j) {}
    nxt[i] = j;
  }
  for (int i = 1; i <= n; ++i) vec[nxt[i]].emplace_back(pre[i] - 1);
  f[0] = 1;
  for (int i = 1; i <= n; ++i) {
    f[i] = 2ll * f[i - 1] % kMod;
    for (auto j : vec[i]) dec(f[i], f[j]);
  }
  std::cout << f[n] << '\n';
}

int32_t main() {
#ifdef ORZXKR
  freopen("in.txt", "r", stdin);
  freopen("out.txt", "w", stdout);
#endif
  std::ios::sync_with_stdio(0), std::cin.tie(0), std::cout.tie(0);
  int T = 1;
  // std::cin >> T;
  while (T--) dickdreamer();
  // std::cerr << 1.0 * clock() / CLOCKS_PER_SEC << "s\n";
  return 0;
}

标签:kMod,int,题解,Serve,kMaxN,ret,bs,First
From: https://www.cnblogs.com/Scarab/p/18451152

相关文章

  • 错误消息:#2002 - Can't connect to local MySQL server through socket '/tmp/mysql.s
    错误消息:#2002-Can'tconnecttolocalMySQLserverthroughsocket'/tmp/mysql.sock'(2)原因:数据库服务未启动。连接参数错误。解决方法:检查数据库服务:确认MySQL服务是否正常运行。sudoservicemysqlstatus检查连接参数:确认连接参数(主机名、用......
  • [ARC112F] Die Siedler 题解
    智慧题。思路考虑第二种操作。我们会想到,我们可以先把所有牌转化成第一种牌。即:\[one=\sum_{i=1}^n\prod_{j=1}^i2^{j-1}(j-1)!c_i\]这就是第一种牌的数量。然后考虑,我们可以将第一种牌转化为第一种牌,花费的代价为:\[g=(\prod_{i=1}^n2^{i-1}(i-1)!)-1\]相当于对\(g\)......
  • P1437 [HNOI2004] 敲砖块 题解
    初拿到手感觉限制太多了,不好硬做,于是开始观察。若要取某一个数,我们要取其左上右上两个数,而这两个数又要取上面三个数,所以取一个数的前提条件其实是取这一个三角形。举例2234582712236493比如我要取第3行的6,我首先要取7和12,要取7和12,首先要取3,4,5,所以一层层拓展......
  • 鲁的女孩 题解
    题意给两个数列,对它进行排列,使得对应两数的和的最大值最小。题解贪心,先将\(a\)、\(b\)排个序(先不考虑时间)。将\(a_1\)与\(a_n\)匹配。\(a_2\)与\(a_{n-1}\)匹配。……取最大值即可。考虑到\(n\le10^5\),不可以暴力枚举。但是\(a,b\le100\),可以开一个桶,......
  • 题解 QOJ1869【Power Station of Art】/ SS241006B【结论题】
    题解QOJ1869【PowerStationofArt】/SS241006B【结论题】PetrozavodskSummer2021.Day6.XJTUContest,GPofXJTUXXIIOpenCupnamedafterE.V.Pankratiev,GrandPrixofXi'an题目描述给出一个无向图,每个点有点权\(a\)和颜色\(c\),其中颜色只会有红蓝两种。......
  • CF131C题解
    传送门:https://codeforces.com/problemset/problem/134/C关注到题目的两个限制:1.一个人只能与另外同一人交换一张卡牌。2.一个人只能交换自己原来颜色的卡牌。对于2条限制条件,显然有贪心思路:尽量让更多的人手持原有的卡牌。对于当前待交换的卡牌,一种构造思路,我们每次贪心选取......
  • 伊吹萃香 题解
    题意(很复杂,真的不想概括,以下是原题面)在幻想乡,伊吹萃香是能够控制物体密度的鬼王。因为能够控制密度,所以萃香能够制造白洞和黑洞,并可以随时改变它们。某一天萃香闲着无聊,在妖怪之山上设置了一些白洞或黑洞,由于引力的影响,给妖怪们带来了很大的麻烦。于是他们决定找出一条消耗体力......
  • CF1117E Decypher the String题解
    传送门神奇的题。这是一道交互题。给定一个字符串\(s\),我们拥有若干操作,但是你不知道,第\(i\)个操作形如\(a_i,b_i\)表示交换字符串\(s\)中的第\(a_i\)位和\(a_j\)位。比如操作序列依次为\((1,2),(2,3)\),给定字符串为xyz。那么我们执行第一次操作后......
  • 题解 QOJ2559【Endless Road】/ SS241006D【套路题】
    PetrozavodskWinter2022.Day2.KAISTContest+KOITST2021XXIIOpenCupnamedafterE.V.Pankratiev,GrandPrixofDaejeon题目描述现在有\(10^9\)个花盆,依次编号为\(1,2,\dots,10^{9}\)。给定\(n\)个二元组\(L_i,R_i(L_i<R_i)\),我们将进行\(n\)次以下操......
  • CF722F Cyclic Cipher 题解
    传送门给定\(n\)个数列,第\(i\)个数列包含\(k_i\)个不超过\(m\)的互不相同的正整数(从\(1\)开始标号)。每一秒将每个数列中的数左移一个位置(即将每个数的下标\(-1\),下标\(1\)的数下标变为\(k_i\)),并记录由每个数列的第一个数组成的序列。\(10^{100}\)秒过......