CF1174E Expected GCD Problem 数论,DP

https://codeforces.com/contest/1174/problem/E

The meaning of problems: gi is defined arrangement p1, p2 ... pi of the GCD (i prefix length of GCD), f (p) is g1, the unique number of elements in g2..gn

Let F m A X ( n ) becomes f (p) at the maximum value of n in the arrangement of all the integer 1, 2 ..., n are given integer, satisfying given f (p) = fmax (n ) are arranged one number mod (1e9 + 7)

Thinking: = arranged for fmax (n) satisfies all f (p), the first element thereof is bound to at most s prime factors. Each time gcd change, which can only be taken away from a quality factor, so that we can ensure that there are as many unique gcd. For s have two inferences:

Corollary 1: s = 2 ^ x * 3 ^ y, i.e., s is only divisible by 2 and 3, because if there are other s prime factor p (p> 4), we can s / p * 4, so can be more multi prime factors.

Corollary 2: y <= 1, because if s = 2 ^ x * 3 ^ y, y> = 2, we can make s = s / 9 * 8, becomes 2 ^ (x + 3) * 3 ^ (y -2), thereby obtaining more prime factor

Establishing dp [i] [x] [y], indicates to the next until the subscript i, the number of the arrangement to meet the requirements, and gcd is 2 ^ x * 3 ^ y. Define a function f (x, y) represents 2 ^ x y ^ 3 * number of multiples, the multiples and <= n

For p (i + 1) has three equations:

Plus 2 ^ x * 3 ^ y is a multiple of, GCD is not changed, the number can be added to f (x, y), but has added the i

dp[i+1][x][y]=dp[i+1][x][y]+dp[i][x][y](f(x,y)i)

1 x reduction, plus a 2 ^ (x-1) * 3 ^ y not simultaneously multiple of 2 ^ x * 3 ^ multiples of y

dp[i+1][x1][y]=dp[i+1][x1][y]+dp[i][x][y](f(x1,y)f(x,y))

y 1 reduction, plus a 2 ^ x * 3 ^ (y-1) at the same time is not a multiple of 2 ^ x * 3 ^ multiples of y

dp[i+1][x][y1]=dp[i+1][x][y1]+dp[i][x][y](f(x,y1)f(x,y))

Always start with 2 ^ x, so dp [1] [x] [0] = 1;

And if 2 ^ (x-1) * 3 <= n, this can also be started so dp [1] [x-1] [1] = 1

years = dp [n] [0] [0]

#include <iostream>
using namespace std;
#define mod 1000000007
int n,dp[1000005][21][2];
int f(int x,int y)
{
    int tmp=(1<<x);
    if (y)
    tmp*=3; return n/tmp; } int main() { scanf("%d",&n); int p=0; while ((1<<p)<=n) p++; p--; dp[1][p][0]=1; if ((1<<(p-1))*3<=n) dp[1][p-1][1]=1; for (int i=1;i<n;i++) { for (int x=0;x<=p;x++) { for (int y=0;y<=1;y++) { dp[i+1][x][y]=(dp[i+1][x][y]+1LL*dp[i][x][y]*(f(x,y)-i))%mod; if (x) dp[i+1][x-1][y]=(dp[i+1][x-1][y]+1LL*dp[i][x][y]*(f(x-1,y)-f(x,y)))%mod; if (y) dp[i+1][x][y-1]=(dp[i+1][x][y-1]+1LL*dp[i][x][y]*(f(x,y-1)-f(x,y)))%mod; } } } printf("%d",dp[n][0][0]); }

 

Guess you like

Origin www.cnblogs.com/hanker99/p/10978931.html
gcd