CF1174E Ehab and the Expected GCD Problem(DP,数论)
题目大意:对于一个序列,定义它的价值是它的所有前缀的 $\gcd$ 中互不相同的数的个数。给定整数 $n$,问在 $1$ 到 $n$ 的排列中,有多少个排列的价值达到最大值。答案对 $10^9+7$ 取模。
$2\le n\le 10^6$。
一道 Div. 2 的难度 2500 的题,真的不是吹的……
首先考虑排列的第一个数 。假如分解质因子后为 $\prod p_i^{c_i}$,那么此时排列价值的最大值为 $\sum c_i$。
为什么?因为如果 $\gcd$ 变了,那么一定变成原来 $\gcd$ 的约数。每次变化 $\sum c_i$ 至少 $-1$。所以最大值就是 $\sum c_i$。
那么排列的价值达到最大值,只有在第一个数的 $\sum c_i$ 达到最大值才可能,并且每次 $\gcd$ 变化只会令 $\sum c_i$ 减小 $1$。
首先发现,质因子 $p_i$ 中不会有 $\ge 5$ 的数。因为此时可以把 $p_i$ 变成 $2^2$,约数更多且仍然合法。
然后,设分解质因子后 $3$ 的次数为 $c$,那么 $0\le c\le 1$。因为当 $c\ge 2$ 时,可以把 $3^2$ 变成 $2^3$,约数更多且仍然合法。
所以第一个数可以被表示成 $2^x3^y$,其中 $y\in\{0,1\}$。
那么就能上DP了。(为什么每次都那么突然……)
设 $f[i][x][y]$ 表示目前填了前 $i$ 位,当前的 $\gcd$ 是 $2^x3^y$,的总合法序列数。
初始状态 $f[1][\lfloor\log_2n\rfloor][0]=1$。如果 $2^{\lfloor\log_2n\rfloor-1}\times 3\le n$,那么还有 $f[1][\lfloor\log_2n\rfloor-1][1]=1$。其它的状态无用,只有这两个状态的 $x+y$ 达到了最大值。
答案为 $f[n][0][0]$。因为排列包含 $1$,所以 $\gcd$ 一定会变为 $1$。
如何转移?(以下设 $cnt(x)=\lfloor\frac{n}{x}\rfloor$,即 $x$ 的倍数的个数)
- $\gcd$ 不变。那么 $f[i][x][y]+=f[i-1][x][y](cnt(2^x3^y)-(i-1))$。因为新选择的数可以是且一定是 $2^x3^y$ 的倍数。然而前 $i-1$ 个位置都是 $2^x3^y$ 的倍数,所以要减掉。
- $\gcd/2$,也就是 $x--$(此时要求 $x<\lfloor\log_2n\rfloor$)。那么 $f[i][x][y]+=f[i-1][x+1][y](cnt(2^x3^y)-cnt(2^{x+1}3^y))$。因为新选择的数一定是 $2^x3^y$ 的倍数,但一定不是 $2^{x+1}3^y$ 的倍数(否则 $\gcd$ 不变)。前 $i-1$ 个位置都是 $2^{x+1}3^y$ 的倍数,所以不用减掉。
- $\gcd/3$,也就是 $y--$(此时要求 $y=0$)。那么 $f[i][x][y]+=f[i-1][x][y+1](cnt(2^x3^y)-cnt(2^x3^{y+1}))$。
时间复杂度 $O(n\log n)$。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
const int maxn=,mod=;
#define MP make_pair
#define PB push_back
#define lson o<<1,l,mid
#define rson o<<1|1,mid+1,r
#define FOR(i,a,b) for(int i=(a);i<=(b);i++)
#define ROF(i,a,b) for(int i=(a);i>=(b);i--)
#define MEM(x,v) memset(x,v,sizeof(x))
inline ll read(){
char ch=getchar();ll x=,f=;
while(ch<'' || ch>'') f|=ch=='-',ch=getchar();
while(ch>='' && ch<='') x=x*+ch-'',ch=getchar();
return f?-x:x;
}
int n,lt,f[maxn][][];
inline int cnt(int x){return n/x;}
int main(){
n=read();
lt=log2(n);
f[][lt][]=;
if((<<(lt-))*<=n) f[][lt-][]=;
FOR(i,,n) FOR(j,,lt){
f[i][j][]=(1ll*f[i-][j][]*(cnt(<<j)-(i-))+1ll*f[i-][j+][]*(cnt(<<j)-cnt(<<(j+)))+1ll*f[i-][j][]*(cnt(<<j)-cnt((<<j)*)))%mod;
f[i][j][]=(1ll*f[i-][j][]*(cnt((<<j)*)-(i-))+1ll*f[i-][j+][]*(cnt((<<j)*)-cnt((<<(j+))*)))%mod;
}
printf("%d\n",f[n][][]);
}
CF1174E Ehab and the Expected GCD Problem(DP,数论)的更多相关文章
- CF1174E Ehab and the Expected GCD Problem(动规+数论+分解)
做法 先来填第一个数,为了保证\(f(p)\)最大,第一个数分解一下为\(\prod\limits_{p_i}p_i^{k_i}\)使得\(\sum\limits_{k_i}\)最大 显然第一个数为\ ...
- Codeforces Round #563 (Div. 2) E. Ehab and the Expected GCD Problem
https://codeforces.com/contest/1174/problem/E dp 好题 *(if 满足条件) 满足条件 *1 不满足条件 *0 ///这代码虽然写着方便,但是常数有点大 ...
- codeforces#1157D. Ehab and the Expected XOR Problem(构造)
题目链接: http://codeforces.com/contest/1174/problem/D 题意: 构造一个序列,满足以下条件 他的所有子段的异或值不等于$x$ $1 \le a_i< ...
- 【CF1174D】 Ehab and the Expected XOR Problem - 构造
题面 Given two integers \(n\) and \(x\), construct an array that satisfies the following conditions: · ...
- CF1174D Ehab and the Expected XOR Problem
思路: 使用前缀和技巧进行问题转化:原数组的任意子串的异或值不能等于0或x,可以转化成前缀异或数组的任意两个元素的异或值不能等于0或x. 实现: #include <bits/stdc++.h& ...
- CF1174D Ehab and the Expected XOR Problem(二进制)
做法 求出答案序列的异或前缀和\(sum_i\),\([l,r]\)子段异或和可表示为\(sum_r\bigoplus sum_{l-1}\) 故转换问题为,填\(sum\)数组,数组内的元素不为\( ...
- CF D. Ehab and the Expected XOR Problem 贪心+位运算
题中只有两个条件:任意区间异或值不等于0或m. 如果只考虑区间异或值不等于 0,则任意两个前缀异或值不能相等. 而除了不能相等之外,还需保证不能出现任意两个前缀异或值不等于m. 即 $xor[i]$^ ...
- Codeforces 798C - Mike and gcd problem(贪心+数论)
题目链接:http://codeforces.com/problemset/problem/798/C 题意:给你n个数,a1,a2,....an.要使得gcd(a1,a2,....an)>1, ...
- Codeforces 1088E Ehab and a component choosing problem
Ehab and a component choosing problem 如果有多个连接件那么这几个连接件一定是一样大的, 所以我们先找到值最大的连通块这个肯定是分数的答案. dp[ i ]表示对于 ...
随机推荐
- RC4算法
RC4算法简介:https://baike.baidu.com/item/RC4%E7%AE%97%E6%B3%95/9686396?fr=aladdin RC4算法java实现: /** * RC4 ...
- Linux 安装Mysql1.8【yum安装】
.下载mysql的yum源 wget http://dev.mysql.com/get/mysql57-community-release-el7-8.noarch.rpm2.安装yum源yum lo ...
- Linux下安装Python3.6.8并安装包
一.问题在Linux下面安装Python3.6.8,由于在Linux中的Python是2.7.x的版本因此,我们需要在Linux中新下载一个Python 二.解决1.python的安装(1)下载包利用 ...
- Mysql中的变量
Mysql中的变量众多(即运行的配置),如:事务相关的.连接相关的.查询优化类的等等. 变量的作用域: 1.临时作用域 session级别:即打开一个与mysql server会话的基础上的作用域,变 ...
- JavaScript 加减危机——为什么会出现这样的结果?
在日常工作计算中,我们如履薄冰,但是 JavaScript 总能给我们这样那样的 surprise~ 0.1 + 0.2 = ? 1 - 0.9 = ? 如果小伙伴给出内心的结果: 0.1 + 0.2 ...
- Spring Security 入门—内存用户验证
简介 作为 Spring 全家桶组件之一,Spring Security 是一个提供安全机制的组件,它主要解决两个问题: 认证:验证用户名和密码: 授权:对于不同的 URL 权限不一样,只有当认证的用 ...
- IIS8.5中的强制https直接修改web.config文件和顶级域名跳转www和过滤子目录不强制跳转
亲测可用 <?xml version="1.0" encoding="UTF-8"?> <configuration> <syst ...
- SQL 去重 DISTINCT 语法
SQL SELECT DISTINCT语句 在表中可能会包含重复值.这并不成问题, 不过有时你也许希望仅仅列出不同(distinct)的值. 关键词DISTINCT 用于返回唯一不同的值 语法 SEL ...
- Linux纯小白操作(以安装JDK为例)
[本文只针对纯小白,有基础的请略过] 最近公司给分配工作使用的虚拟机都是Linux系统的,以前完全没接触过,今天按照网上一些教程操作,好多地方感觉对小白不够友好(有些问题非常小白那些教程没有写出来.我 ...
- Cocos Creator 返回字符串长度(字符),汉字计数为2
function strLength(str) { var a = 0; for (var i = 0; i < str.length; i++) { if (str.charCodeAt(i) ...