AtCoder AGC032F One Third (combination count, DP, the desired probability, calculus)

Topic Link

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

answer

Immortal title. .
The first step in the conversion using the \ (\ frac {1} { 3} \) the number of unique properties. Suppose we red mark the position of each cut, and then in the clockwise position of each cut \ (120 \) at a degree indicated by the blue line, then the answer is equal to the minimum angle between the red line and the blue line. But this is still not finished doing conversion (and seems to be useless \ (\ frac {1} { 3} \) particularity), consider if the position of each cut counterclockwise \ (120 \) degrees indicated by the green line, the answer is still the same, because \ (| X-\ FRAC. 1 {{}}. 3 | = | (. 1-X) - \ FRAC. 3} {2} {| \) . as we is equivalent to the entire circumference into the \ (3 \) aliquots (each aliquot referred to as \ (\ FRAC. 1} {3} {\) ), a consideration which, in each position where a random stochastic three colors of one line Videos (initially at \ (0 \) there is a red line \ (\ frac {1} { 3} \) at has a blue line), the answer is equal to the shortest distance between different colors expectations.
Not sprinkled with a total end to end \ ((n-1) \ ) points, the \ ([0, \ frac { 1} {3}] \) into the \ (n-\) parts. Calculated considering how parts of different colors on both ends (referred to as "different color segments") is the desired minimum length.
Consider first a weakened version of the problem: There is no limit color, with\ ((k-1) \ ) points to \ ([0,1] \) into \ (K \) parts, a minimum desired length. Greater than or equal to consider the answer \ (T \) probability, it is equivalent \ (n-\) random real numbers and is \ (1-kt \) is divided by the probability \ (n-\) random real numbers and is \ (1 \) the probability, that is, \ ((n-1) \ ) random real numbers and not more than \ (1-kt \) probability divided by \ ((n-1) \ ) random real numbers and not more than \ ( 1 \) probability, apparently equal \ ((KT-1) K-1} ^ {\) . so its integration, \ (\ int ^ \ {1} {K FRAC} _0 (KT-1) ^ {k-1} \ text { d} t = \ frac {1} {k} \ int ^ 1_0 (1-t) ^ {k-1} dt = \ frac {1} {k} \ int ^ 1_0t ^ . 1-K} {\ text {D} T = \ FRAC. 1} {2} {K ^ \) ., and the \ ([0,1] \) into \ ([0, L] \ ) push apparent answers \ (L \) is linear, i.e., \ (\ K FRAC {L} ^ {2} \) .
For color restrictions, different considerations and enumerate the number of color segments, divided into two parts: (1) the probability of this occurrence; (2) a desired answer to the question in this case. For (2), obviously a total length for the different color segments of a desired \ (\ frac {K} {} with 3N \) , as answer to the above question, so the answer on a desired overall length is linear is the \ (\ frac { }} {3nk. 1 \) . For (1), may be multiplied by the number of combinations is obtained with a DP, DP number of different color segments, the same number of combinations of color segments inserted.
The total time complexity \ (O (n-) \) .

Code

#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;
}

Guess you like

Origin www.cnblogs.com/suncongbo/p/12233568.html