• 【洛谷6261】[ICPC2019 WF] Traffic Blights(数论)


    点此看题面

    • 一条路上有(n)个红绿灯,第(i)个红绿灯在(x_i)位置上。
    • (0)时刻开始计算,第(i)个红绿灯会红(r_i)秒,绿(g_i)秒,如是循环。
    • 在某个随机时刻出发,对于每个红绿灯求出最早在它停下的概率,并求出能走到最后的概率。
    • (nle500,r_i+g_ile100)

    几种特殊情况

    假设起始时刻为(s),令(p_i=r_i+g_i),那么不能通过第(i)个红绿灯就意味着((s+x_i)\% p_i<r_i)

    (f_i)表示在第(i)个红绿灯不停下的概率,那么停在第(i)个红绿灯的概率就是(f_{i-1}-f_i)

    如果(p_i)两两互质,概率可以直接相乘。

    如果(p_i)两两相等,可以直接对覆盖的区间求交。实际上,如果(p_i)两两具有倍数关系,也可以把区间赋值若干份,使得所有的(p_i)都被调成一样。

    如果(p_i)要么互质,要么成倍数关系,可以对于每个成倍数关系的部分按照第二种情况的方式求解,然后按照第一种情况把每一部分概率相乘。

    现在我们希望把所有情况都化乘这里的第三种情况。

    巧妙的数学手法

    (P=2^3 imes3^2 imes5 imes7=2520),我们枚举模(P)的余数(t),那么所有的时间都可以被表示成(kP+t)的形式。

    由于(kP+tequiv r(mod p_i))的模数可以被替换为(frac {p_i}{gcd(P,p_i)}),而(100)以内的数除以与(2520)(gcd)之后最多剩余一种质因子,满足了所有(p_i')要么互质要么成倍数关系,就可以套用上面的做法了。

    代码:(O(2520np))

    #include<bits/stdc++.h>
    #define Tp template<typename Ty>
    #define Ts template<typename Ty,typename... Ar>
    #define Reg register
    #define RI Reg int
    #define Con const
    #define CI Con int&
    #define I inline
    #define W while
    #define N 500
    #define V 100
    #define P 2520
    #define DB long double
    using namespace std;
    int n,p[N+5],tg[N+5][V+5];DB f[N+5];
    I int gcd(CI x,CI y) {return y?gcd(y,x%y):x;}
    I int T(CI x) {return x==2||x==4?8:(x==3?9:x);}//把x调到可能的最大倍数
    DB k[V+5];int vis[V+5][V+5];I void Solve(CI t)//余数为t时
    {
    	RI i,j;for(i=1;i<=V;++i) k[i]=1;memset(vis,0,sizeof(vis));//初始化
    	RI x,w;DB o=1;for(++f[0],i=1;i<=n&&o>1e-12;f[i++]+=(o*=k[w]))
    		for(o/=k[w=T(p[i]/gcd(P,p[i]))],j=0;j^w;++j) tg[i][x=(j*P+t)%p[i]]&&!vis[w][j]&&(k[w]-=1.0/w,vis[w][j]=1);//枚举时间jP+t
    }
    int main()
    {
    	RI i,j,x,y;for(scanf("%d",&n),i=1;i<=n;++i)
    		for(scanf("%d%d%d",&x,&y,p+i),x%=(p[i]+=y),j=0;j^y;++j) tg[i][(j-x+p[i])%p[i]]=1;//给红灯对应余数打标记
    	for(i=0;i^P;++i) Solve(i);for(i=1;i<=n+1;++i) printf("%.12Lf
    ",(f[i-1]-f[i])/P);return 0;//枚举模P余数,最终答案要除以P
    }
    
    败得义无反顾,弱得一无是处
  • 相关阅读:
    linux上java和golang环境变量的设置
    MySQL踩坑及MySQL解压版安装
    Mysql踩坑 自动更新的时间只允许有一个
    从零开始学习PYTHON3讲义(十五)让画面动起来
    从零开始学习PYTHON3讲义(十四)写一个mp3播放器
    从零开始学习PYTHON3讲义(十三)记事本的升级版:网络记事本
    从零开始学习PYTHON3讲义(十二)画一颗心送给你
    从零开始学习PYTHON3讲义(十一)计算器升级啦
    从零开始学习PYTHON3讲义(十)自己做一个“电子记事本”
    从零开始学习PYTHON3讲义(九)字典类型和插入排序
  • 原文地址:https://www.cnblogs.com/chenxiaoran666/p/Luogu6261.html
Copyright © 2020-2023  润新知