Luogu3600 随机数生成器

题面

传送门

Sol

\(sto \ \\) \(fdf\)
\(sto \ \\) \(fateice\)

显然,如果一个区间包含了另一个区间,那么它的最小值不会有贡献,直接去掉

考虑枚举最大值\(k\)
求出所有区间满足最小值小于等于\(k\)的概率,设为\(P[k]\)
那么\(k\)的贡献就是\((P[k]-P[k-1])*k\),相当于差分了一下

然后考虑算出\(P[k]\)
\(f[i]\)表示到\(i\)时,所有右端点都小于等于\(i\)的区间都满足要求的概率
枚举右端点在\(i\)的所有左端点\(j\)
枚举在哪里弄一个小于等于\(k\)
\[f[i]=\sum_{l=j}^{i}f[l-1]*(\frac{k}{x})*(1-\frac{k}{x})^{i-l}\]

枚举的这个点之前的随便选,而后面的只能选大于\(k\)
这样才能做到不重复计算,因为如果后面的也随便选,那么会和之前的有交集
然后这是\(n^3x\)的,居然过了
\(n,x<=2000\)

把上面的转移式拆一下,把\(f[l-1]*(1-\frac{k}{x})^{-l}\)做个前缀和就好了
特别注意如果\(i=l\)并且\(k=x\)时,\((1-\frac{k}{x})^{i-l}\)要当成\(1\)
那么特判一下就好了

\(fdf\) $   orz$
\(fateice\) $   orz$

# include <bits/stdc++.h>
# define RG register
# define IL inline
# define Fill(a, b) memset(a, b, sizeof(a))
using namespace std;
typedef long long ll;
const int _(2005);
const int Zsy(666623333);

IL int Input(){
    RG int x = 0, z = 1; RG char c = getchar();
    for(; c < '0' || c > '9'; c = getchar()) z = c == '-' ? -1 : 1;
    for(; c >= '0' && c <= '9'; c = getchar()) x = (x << 1) + (x << 3) + (c ^ 48);
    return x * z;
}

int n, x, Q, tp, f[_], g[_], ans, first[_], nxt[_], inv;
struct Query{
    int l, r;

    IL int operator <(RG Query B) const{
        return l != B.l ? l < B.l : r < B.r;
    }
} tmp[_], q[_];

IL int Pow(RG ll x, RG ll y){
    RG ll ret = 1;
    for(; y; y >>= 1, x = x * x % Zsy)
        if(y & 1) ret = ret * x % Zsy;
    return ret;
}

IL void Upd(RG int &x, RG int y){
    x += y;
    if(x >= Zsy) x -= Zsy;
}

IL int Sum(RG int l, RG int r){
    return (g[r] - (l < 0 ? 0 : g[l]) + Zsy) % Zsy;
}

IL int Calc(RG int v){
    RG int p1 = 1LL * inv * v % Zsy, p2 = (1 + Zsy - p1) % Zsy, p3 = Pow(p2, Zsy - 2);
    Fill(g, 0), Fill(f, 0), g[0] = p3, f[0] = 1;
    for(RG int i = 1; i <= n; ++i){
        for(RG int p = first[i]; p; p = nxt[p]){
            if(i > q[p].l) Upd(f[i], 1LL * Sum(q[p].l - 2, i - 2) * p1 % Zsy * Pow(p2, i) % Zsy);
            Upd(f[i], 1LL * f[i - 1] * p1 % Zsy);
        }
        if(!first[i]) f[i] = f[i - 1];
        g[i] = g[i - 1], Upd(g[i], 1LL * f[i] * Pow(p3, i + 1) % Zsy);
    }
    return f[n];
}

int main(RG int argc, RG char *argv[]){
    n = Input(), x = Input(), tp = Input(), inv = Pow(x, Zsy - 2);
    for(RG int i = 1; i <= tp; ++i) tmp[i] = (Query){Input(), Input()};
    sort(tmp + 1, tmp + tp + 1);
    for(RG int i = 1; i <= tp; ++i){
        while(q[Q].r >= tmp[i].r) --Q;
        if(tmp[i].l > q[Q].l) q[++Q] = tmp[i];
    }
    for(RG int i = 1; i <= Q; ++i) nxt[i] = first[q[i].r], first[q[i].r] = i;
    for(RG int i = 1, lst = 0; i <= x; ++i){
        RG int now = Calc(i);
        ans = (ans + 1LL * i * ((now - lst + Zsy) % Zsy) % Zsy) % Zsy;
        lst = now;
    }
    printf("%d\n", ans);
    return 0;
}

转载于:https://www.cnblogs.com/cjoieryl/p/8665132.html

资源下载链接为: https://pan.quark.cn/s/d9ef5828b597 四路20秒声光显示计分抢答器Multisim14仿真源文件+设计文档资料摘要 数字抢答器由主体电路与扩展电路组成。优先编码电路、锁存器、译码电路将参赛队的输入信号在显示器上输出;用控制电路和主持人开关启动报警电路,以上两部分组成主体电路。通过定时电路和译码电路将秒脉冲产生的信号在显示器上输出实现计时功能,构成扩展电路。经过布线、焊接、调试等工作后数字抢答器成形。关键字:开关阵列电路;触发锁存电路;解锁电路;编码电路;显示电路 一、设计目的 本设计是利用已学过的数电知识,设计的4人抢答器。(1)重温自己已学过的数电知识;(2)掌握数字集成电路的设计方法和原理;(3)通过完成该设计任务掌握实际问题的逻辑分析,学会对实际问题进行逻辑状态分配、化简;(4)掌握数字电路各部分电路与总体电路的设计、调试、模拟仿真方法。 二、整体设计 (一)设计任务与要求: 抢答器同时供4名选手或4个代表队比赛,分别用4个按钮S0 ~ S3表示。 设置一个系统清除和抢答控制开关S,该开关由主持人控制。 抢答器具有锁存与显示功能。即选手按动按钮,锁存相应的编号,并在LED数码管上显示,同时扬声器发出报警声响提示。选手抢答实行优先锁存,优先抢答选手的编号一直保持到主持人将系统清除为止。 参赛选手在设定的时间内进行抢答,抢答有效,定时器停止工作,显示器上显示选手的编号和抢答的时间,并保持到主持人将系统清除为止。 如果定时时间已到,无人抢答,本次抢答无效。 (二)设计原理与参考电路 抢答器的组成框图如下图所示。它主要由开关阵列电路、触发锁存电路、解锁电路、编码电路和显示电路等几部分组成。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值