CF1948F 题解

对于每个询问,可以把这 rl+1 个袋子合并成一个 有 i=lrai 个金币和 i=lrbi 个银币的袋子。[l,r] 外的袋子同理也可以这样合并。

假设 suma=i=1nai,sumb=i=1nbiina=i=lrai,inb=l=1rbi, outa=sumaina,outb=sumbinb

那么原问题就是查询 ina+rand(inb)>outa+rand(outb) 的概率,其中 rand(x) 表示 x 个银币时的随机取值。把上面的式子中符号两边的 rand 移到同一边,得到:

rand(inb)rand(outb)>outaina

观察到 inb+outb=sumb,那么尝试把 rand(inb)rand(outb) 变成 rand(inb)+rand(outb)。只需两边同时加上 outb,式子变成:

rand(inb)+rand(outb)>outa+outbina

接着又有 rand(inb)+rand(outb)=rand(inb+outb)=rand(sumb),所以最终转化成了:

rand(sumb)>outa+outbina

其中 outa+outbina 是可以 Θ(1) 求得的,设 Q=outa+outbina,那么答案是:

x=Q+1sumb(sumbx)×(12)n

预处理组合数后缀和即可,复杂度为 O(n)

code:

#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
const int N = 2E6 + 5;
template <class T>
T power(T a, long long b) {
  T res = 1;
  for (; b; b >>= 1, a *= a) {
    if (b & 1)
      res *= a;
  } return res;
}
#define C constexpr
#define FC friend constexpr
#define OP operator
template <long long mod>
class ModLL {
  public:
    long long n;
    static long long Mod;
    C ModLL() : n{} {}
    C ModLL(long long x) : n(norm(x % getmod())) {}
    C long long norm(long long x) {
      if (x >= getmod()) x %= getmod();
      if (x <= -getmod()) x %= getmod();
      if (x < 0) x += getmod();
      return x;
    }
    C long long getmod() {return (mod > 0 ? mod : Mod);}
    explicit C OP long long() const {return n;}
    C ModLL OP -() const {ModLL a; a.n = norm(getmod() - n); return a;}
    C ModLL inv() {assert(n != 0); return power((*this), getmod() - 2);}
    C ModLL &OP += (ModLL w) & {n = norm( n + w.n); return (*this);}
    C ModLL &OP -= (ModLL w) & {n = norm( n - w.n); return (*this);}
    C ModLL &OP *= (ModLL w) & {n = norm( 1LL * n * w.n % getmod()); return (*this);}
    C ModLL &OP /= (ModLL w) & {return (*this) *= w.inv();}
    FC ModLL OP + (ModLL a, ModLL b) {ModLL res = a; res += b; return res;}
    FC ModLL OP - (ModLL a, ModLL b) {ModLL res = a; res -= b; return res;}
    FC ModLL OP * (ModLL a, ModLL b) {ModLL res = a; res *= b; return res;}
    FC ModLL OP / (ModLL a, ModLL b) {ModLL res = a; res /= b; return res;}
    FC bool OP == (ModLL a, ModLL b) {return (a.n == b.n);}
    FC bool OP != (ModLL a, ModLL b) {return (a.n != b.n);}
    FC istream &OP >> (istream &is, ModLL &a) {
      long long x = 0; is >> x;
      a = ModLL(x); return is;
    }
    FC ostream &OP << (ostream &os, const ModLL &a) {return (os << (a.n));}
} ; 
template <int mod>
class ModInt {
  public:
    int n;
    static int Mod;
    C ModInt() : n{} {}
    C ModInt(int x) : n(norm(x % getmod())) {}
    C int norm(int x) {
      if (x >= getmod()) x %= getmod();
      if (x <= -getmod()) x %= getmod();
      if (x < 0) x += getmod();
      return x;
    }
    C static int getmod() {return (mod > 0 ? mod : Mod);}
    explicit C OP int() const {return n;}
    C ModInt OP -() const {ModInt a; a.n = norm(getmod() - n); return a;}
    C ModInt inv() const {assert(n != 0); return power((*this), getmod() - 2);}
    C ModInt &OP += (ModInt w) & {n = norm( n + w.n); return (*this);}
    C ModInt &OP -= (ModInt w) & {n = norm( n - w.n); return (*this);}
    C ModInt &OP *= (ModInt w) & {n = norm( 1LL * n * w.n % getmod()); return (*this);}
    C ModInt &OP /= (ModInt w) & {return (*this) *= w.inv();}
    FC ModInt OP + (ModInt a, ModInt b) {ModInt res = a; res += b; return res;}
    FC ModInt OP - (ModInt a, ModInt b) {ModInt res = a; res -= b; return res;}
    FC ModInt OP * (ModInt a, ModInt b) {ModInt res = a; res *= b; return res;}
    FC ModInt OP / (ModInt a, ModInt b) {ModInt res = a; res /= b; return res;}
    FC bool OP == (ModInt a, ModInt b) {return (a.n == b.n);}
    FC bool OP != (ModInt a, ModInt b) {return (a.n != b.n);}
    FC istream &OP >> (istream &is, ModInt &a) {
      int x = 0; is >> x;
      a = ModInt(x); return is;
    }
    FC ostream &OP << (ostream &os, const ModInt &a) {return (os << (a.n));}
} ; 
template <>
long long ModLL <0> :: Mod = (long long)(1E18) + 9;
template <>
int ModInt <0> :: Mod = 998244353;
using P = ModInt <998244353>;
#undef C
#undef FC
#undef OP
signed main(void) {
  ios :: sync_with_stdio(false);
  cin.tie(0); cout.tie(0);
  int n, q; cin >> n >> q;
  vector <int> a(n + 1), b(n + 1);
  for (int i = 1; i <= n; ++i) cin >> a[i];
  for (int i = 1; i <= n; ++i) cin >> b[i];
  vector <int> suma(n + 1), sumb(n + 1);
  for (int i = 1; i <= n; ++i) {
    suma[i] = suma[i - 1] + a[i];
    sumb[i] = sumb[i - 1] + b[i];
  }
  vector <P> comb(sumb[n] + 1), fac(sumb[n] + 1); fac[0] = 1;
  for (int i = 1; i <= sumb[n]; ++i) fac[i] = fac[i - 1] * i;
  comb[sumb[n]] = 1;
  for (int i = sumb[n] - 1; i >= 0; --i) 
    comb[i] = comb[i + 1] + (fac[sumb[n]] / fac[i] / fac[sumb[n] - i]);
  P div = power(P(2), sumb[n]);
  for (int i = 1; i <= q; ++i) {
    int l, r; cin >> l >> r;
    --l;
    int in_a = suma[r] - suma[l], in_b = sumb[r] - sumb[l];
    int out_a = suma[n] - in_a, out_b = sumb[n] - in_b;
    int Q = out_a + out_b - in_a;
    if (Q >= sumb[n]) cout << 0 << ' ';
    else if (Q < 0) cout << 1 << ' ';
    else cout << comb[Q + 1] / div << ' ';
  }
  return 0;
}

作者:CTHOOH

出处:https://www.cnblogs.com/CTHOOH/p/18076821

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

posted @   CTHOOH  阅读(128)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
more_horiz
keyboard_arrow_up light_mode palette
选择主题
点击右上角即可分享
微信分享提示