AtCoder AGC032F One Third (组合计数、DP、概率期望、微积分)

题目链接

https://atcoder.jp/contests/agc032/tasks/agc032_f

题解

神仙题。。
第一步转化利用了\(\frac{1}{3}\)这个数特有的性质。假设我们用红线标出每一次切割的位置,再在每一次切割的位置顺时针\(120\)度处用蓝线标出,那么答案就等于红线与蓝线之间的最小夹角。但是这样转化完了依然不好做(而且似乎也没用到\(\frac{1}{3}\)的特殊性),那么考虑如果在每一次切割的位置逆时针\(120\)度处用绿线标出,答案依然是不变的,因为\(|x-\frac{1}{3}|=|(1-x)-\frac{2}{3}|\). 那样我们就相当于将整个圆周分成了\(3\)等份(每一等份记作\(\frac{1}{3}\)),考虑其中的一份,每次在其中随机一个位置随机三种颜色中的一种画上线(初始时在\(0\)处有一条红线\(\frac{1}{3}\)处有一条蓝线),答案等于不同颜色之间最短距离的期望。
不算首尾一共撒了\((n-1)\)个点,将\([0,\frac{1}{3}]\)分成了\(n\)份。考虑如何算两端为不同颜色的份(下称“不同色段”)的最短长度的期望。
首先考虑一个弱化版问题: 没有颜色的限制,用\((k-1)\)个点把\([0,1]\)分成\(k\)份,最小的一份的期望长度。考虑答案大于等于\(t\)的概率,也就相当于\(n\)个随机实数和为\(1-kt\)的概率除以\(n\)个随机实数和为\(1\)的概率,也就是\((n-1)\)个随机实数和不超过\(1-kt\)的概率除以\((n-1)\)个随机实数和不超过\(1\)的概率,显然等于\((1-kt)^{k-1}\). 那么对其进行积分,\(\int^\frac{1}{k}_0(1-kt)^{k-1}\text{d}t=\frac{1}{k}\int^1_0(1-t)^{k-1}dt=\frac{1}{k}\int^1_0t^{k-1}\text{d}t=\frac{1}{k^2}\). 并且把\([0,1]\)换成\([0,L]\)推一下可知答案关于\(L\)是线性的,即\(\frac{L}{k^2}\).
对于有颜色限制的情况,考虑枚举不同色段的个数,分成两部分:(1)出现这种情况的概率;(2)在这种情况下答案的期望。对于(2),显然不同色段的总长度期望为\(\frac{k}{3n}\), 因为上面问题的答案关于总长度是线性的,因此答案的期望即为\(\frac{1}{3nk}\)。对于(1),可以用一个DP乘以组合数来求出,DP不同色段的个数,组合数插入同色段。
总时间复杂度\(O(n)\).

代码

#include<bits/stdc++.h>
#define llong long long
using namespace std;

inline int read()
{
    int x = 0,f = 1; char ch = getchar();
    for(;!isdigit(ch);ch=getchar()) {if(ch=='-') f = -1;}
    for(; isdigit(ch);ch=getchar()) {x = x*10+ch-48;}
    return x*f;
}

const int N = 1e6;
const llong P = 1e9+7;
const llong INV3 = 333333336ll;
llong fact[N+3],finv[N+3];

llong quickpow(llong x,llong y)
{
    llong cur = x,ret = 1ll;
    for(int i=0; y; i++) {if(y&(1ll<<i)) {ret = ret*cur%P; y-=(1ll<<i);} cur = cur*cur%P;}
    return ret;
}
llong comb(llong x,llong y) {return x<0||y<0||x<y?0ll:fact[x]*finv[y]%P*finv[x-y]%P;}

llong f[N+3][3];
int n;

void updsum(llong &x,llong y) {x = x+y>=P?x+y-P:x+y;}

int main()
{
    fact[0] = 1ll; for(int i=1; i<=N; i++) fact[i] = fact[i-1]*i%P;
    finv[N] = quickpow(fact[N],P-2); for(int i=N-1; i>=0; i--) finv[i] = finv[i+1]*(i+1)%P;
    scanf("%d",&n);
    f[0][0] = 1ll;
    for(int i=1; i<=n; i++) for(int j=0; j<3; j++) for(int k=0; k<3; k++) {if(k!=j) updsum(f[i][j],f[i-1][k]);}
    llong ans = 0ll;
    for(int i=1; i<=n; i++)
    {
        llong cur = f[i][1]*comb(n,i)%P*finv[i]%P*fact[i-1]%P; updsum(ans,cur);
    }
    ans = ans*finv[n]%P*fact[n-1]%P*quickpow(INV3,n)%P;
    printf("%lld\n",ans);
    return 0;
}

原文地址:https://www.cnblogs.com/suncongbo/p/12233568.html

时间: 2024-07-30 22:22:20

AtCoder AGC032F One Third (组合计数、DP、概率期望、微积分)的相关文章

HDU 4832 组合计数dp

Chess Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 509    Accepted Submission(s): 198 Problem Description 小度和小良最近又迷上了下棋.棋盘一共有N行M列,我们可以把左上角的格子定为(1,1),右下角的格子定为(N,M).在他们的规则中,"王"在棋盘上的走法遵循十字

[ZJOI2010]排列计数 (组合计数/dp)

[ZJOI2010]排列计数 题目描述 称一个1,2,...,N的排列P1,P2...,Pn是Magic的,当且仅当2<=i<=N时,Pi>Pi/2. 计算1,2,...N的排列中有多少是Magic的,答案可能很大,只能输出模P以后的值 输入输出格式 输入格式: 输入文件的第一行包含两个整数 n和p,含义如上所述. 输出格式: 输出文件中仅包含一个整数,表示计算1,2,?, 的排列中, Magic排列的个数模 p的值. 输入输出样例 输入样例#1: 20 23 输出样例#1: 16 说明

AtCoder AGC036C GP 2 (组合计数)

题目链接 https://atcoder.jp/contests/agc036/tasks/agc036_c 题解 终于有时间补agc036的题了. 这题其实不难的来着--我太菜了考场上没想出来 首先转化一下题目: 一个序列可以被按题目的操作方式生成当且仅当它长度为\(N\), 总和为\(3M\), 且最大数不超过\(2M\), 奇数的个数不超过\(M\). 必要性显然,充分性归纳易证. 然后考虑怎么计数: 先不考虑第二个条件,定义\(f(n,m,k)\)表示长度为\(n\)总和为\(m\)奇数

Singer House CodeForces - 830D (组合计数,dp)

大意: 一个$k$层完全二叉树, 每个节点向它祖先连边, 就得到一个$k$房子, 求$k$房子的所有简单路径数. $DP$好题. 首先设$dp_{i,j}$表示$i$房子, 分出$j$条简单路径的方案数, 那么最终答案就为$dp_{i,1}$. 考虑两棵$i-1$房子转移到$i$房子的情况, 分四种情况. 两个子树间不与根节点连边, 那么$dp_{i,j+k}=\sum dp_{i-1,j}dp_{i-1,k}$ 两个子树只有一条路径与根节点连边, $dp_{i,j+k}=\sum dp_{i-

AtCoder AGC035F Two Histograms (组合计数、容斥原理)

题目链接 https://atcoder.jp/contests/agc035/tasks/agc035_f 题解 B题难度的F题--然而我还是不会 假设第\(i\)行染的长度是\(a_i\), 第\(j\)列是\(b_j\) 考虑什么情况下两种方案会重复: 若存在\(i,j\)使得\(a_i+1=j\)且\(b_j=i\), 那么令\(a'_i=j-1,b'_j=i+1\)可以得到一样的结果. 那么我们也就是要计算不存在\(a_i+1=j\)且\(b_j=i\)的序列\(a,b\)个数. 充分

hdu4779 组合计数+dp

提交 题意:给了n*m的网格,然后有p个重型的防御塔,能承受1次攻击,q个轻型防御塔不能接受任何攻击,然后每个防御搭会攻击他所在的行和所在的列,最后求在这个网格上放至少一个防御塔的方案数, 我们枚举 选取多少个重型防御塔然后这个重型防御塔有多少是两个在一行,和两个在一列 O(P^3)的效率 #include <iostream> #include <algorithm> #include <cstdio> #include <string.h> #inclu

hdu-5816 Hearthstone(状压dp+概率期望)

题目链接: Hearthstone Time Limit: 2000/1000 MS (Java/Others)     Memory Limit: 65536/65536 K (Java/Others) Problem Description Hearthstone is an online collectible card game from Blizzard Entertainment. Strategies and luck are the most important factors

【BZOJ】4559: [JLoi2016]成绩比较 计数DP+排列组合+拉格朗日插值

[题意]n位同学(其中一位是B神),m门必修课,每门必修课的分数是[1,Ui].B神碾压了k位同学(所有课分数<=B神),且第x门课有rx-1位同学的分数高于B神,求满足条件的分数情况数.当有一位同学的一门必修课分数不同时视为两种情况不同.n,m<=100,Ui<=10^9. [算法]计数DP+排列组合+拉格朗日插值 [题解]把分数作为状态不现实,只能逐门课考虑. 设$f[i][j]$表示前i门课,有j个同学被碾压的情况数,则有: $$f[i][j]=g(i)\cdot\sum_{k=j

3.29省选模拟赛 除法与取模 dp+组合计数

LINK:除法与取模 鬼题.不过50分很好写.考虑不带除法的时候 其实是一个dp的组合计数. 考虑带除法的时候需要状压一下除法操作. 因为除法操作是不受x的大小影响的 所以要状压这个除法操作. 直接采用二进制状压是不明智的 2的个数最多为13个 2^13也同样到达了1e4的复杂度. 考虑 hash状压 即 2的个数有x个 那么我们就有状态w表示2还有x个. 这样做的原因是把一些相同的东西给合并起来 而并非分散开来.即有多个2直接记录有多少个即可. 可以发现 这样做不同的除数最多只有5个 状态量较