【取对数】【哈希】Petrozavodsk Winter Training Camp 2018 Day 1: Jagiellonian U Contest, Tuesday, January 30, 2018 Problem J. Bobby Tables
题意:给你一个大整数X的素因子分解形式,每个因子不超过m。问你能否找到两个数n,k,k<=n<=m,使得C(n,k)=X。
不妨取对数,把乘法转换成加法。枚举n,然后去找最大的k(<=n/2),使得ln(C(n,k))<=ln(X),然后用哈希去验证是否恰好等于ln(X)。
由于n和k有单调性,所以枚举其实是O(m)。
妈的这个哈希思想贼巧妙啊,因为对数使得精度爆炸,所以不妨同步弄个哈希值,来判相等。
opencup的标程:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
#include "bits/stdc++.h"
using namespace std; using UInt = unsigned long long;
using Float = long double; const int M = 150 * 1000; Float LogSum[M+1];
UInt Hash[M+1];
UInt HashSum[M+1]; void Init(int m) {
// LogF
LogSum[0] = 0.;
for (int i = 1; i <= m; ++i) {
LogSum[i] = LogSum[i-1] + log((Float) i);
} // Hash, HashF
std::mt19937 gen;
uniform_int_distribution<UInt> distr;
vector<int> sieve(m+1, 0);
for (int i = 2; i * i <= m; ++i) {
if (sieve[i] == 0) {
for (int j = i * i; j <= m; j += i) {
sieve[j] = i;
}
}
}
Hash[0] = Hash[1] = 0;
for (int i = 2; i <= m; ++i) {
if (sieve[i] == 0) {
Hash[i] = distr(gen);
} else {
Hash[i] = Hash[i/sieve[i]] + Hash[sieve[i]];
}
}
partial_sum(Hash, Hash + m + 1, HashSum);
} Float LogBinom(int n, int k) {
return LogSum[n] - LogSum[n-k] - LogSum[k];
} UInt HashBinom(int n, int k) {
return HashSum[n] - HashSum[n-k] - HashSum[k];
} bool Solve(const vector<int>& factors, int m, int& n, int& k) {
for (int p : factors) {if (p > m) { return false; }}
Float log_x = 0;
UInt hash_x = 0;
for (int p : factors) { log_x += log((Float) p); hash_x += Hash[p]; } //check
int b = m;
for (int a = 0; a <= m; ++a) {
while (b > 0 && (a + b - 1 > m || LogBinom(a+b-1, a) >= log_x)) { --b; }
if (b > 0 && HashBinom(a + b - 1, a) == hash_x) {
n = a + b - 1;
k = a;
return true;
}
if (a + b <= m && HashBinom(a+b, a) == hash_x) {
n = a + b;
k = a;
return true;
}
}
return false;
} int main() {
Init(M);
ios_base::sync_with_stdio(false);
int z;
cin >> z;
while (z--) {
int t;
int m;
cin >> t >> m;
vector<int> factors(t);
for (int i = 0; i < t; ++i) {
cin >> factors[i];
} //assert(t != 0);
int n, k;
if (Solve(factors, m, n, k)) {
cout << "YES\n";
cout << n << ' ' << k << '\n';
} else {
cout << "NO\n";
}
}
}
【取对数】【哈希】Petrozavodsk Winter Training Camp 2018 Day 1: Jagiellonian U Contest, Tuesday, January 30, 2018 Problem J. Bobby Tables的更多相关文章
- 【模拟退火】Petrozavodsk Winter Training Camp 2017 Day 1: Jagiellonian U Contest, Monday, January 30, 2017 Problem F. Factory
让你在平面上取一个点,使得其到给定的所有点的距离和最小. 就是“费马点”. 模拟退火……日后学习一下,这是从网上扒的,先存下. #include<iostream> #include< ...
- 【动态规划】【二分】Petrozavodsk Winter Training Camp 2017 Day 1: Jagiellonian U Contest, Monday, January 30, 2017 Problem B. Dissertation
题意: 给定S1串,长度100w,S2串,长度1k.问它俩的LCS. f(i,j)表示S2串前i个字符,LCS为j时,最少需要的S1串的前缀长度.转移的时候,枚举下一个字符在S1的位置即可.(可以预处 ...
- 【二分】Petrozavodsk Winter Training Camp 2017 Day 1: Jagiellonian U Contest, Monday, January 30, 2017 Problem A. The Catcher in the Rye
一个区域,垂直分成三块,每块有一个速度限制,问你从左下角跑到右上角的最短时间. 将区域看作三块折射率不同的介质,可以证明,按照光路跑时间最短. 于是可以二分第一个入射角,此时可以推出射到最右侧边界上的 ...
- 【状压dp】Petrozavodsk Winter Training Camp 2018 Day 1: Jagiellonian U Contest, Tuesday, January 30, 2018 Problem E. Guessing Game
题意:给你n个两两不同的零一串,Alice在其中选定一个,Bob去猜,每次询问某一位是0 or 1.问你最坏情况下最少要猜几次. f(22...2)表示当前状态的最小步数,2表示这位没确定,1表示确定 ...
- 【BFS】【最小生成树】Petrozavodsk Winter Training Camp 2018 Day 1: Jagiellonian U Contest, Tuesday, January 30, 2018 Problem G. We Need More Managers!
题意:给你n个点,点带权,任意两点之间的边权是它们的点权的异或值中“1”的个数,问你该图的最小生成树. 看似是个完全图,实际上有很多边是废的.类似……卡诺图的思想?从读入的点出发BFS,每次只到改变它 ...
- 【推导】【单调性】Petrozavodsk Winter Training Camp 2018 Day 1: Jagiellonian U Contest, Tuesday, January 30, 2018 Problem B. Tribute
题意:有n个数,除了空集外,它们会形成2^n-1个子集,给你这些子集的和的结果,让你还原原来的n个数. 假设原数是3 5 16, 那么它们形成3 5 8 16 19 21 24, 那么第一轮取出开头的 ...
- 【线性基】Petrozavodsk Winter Training Camp 2018 Day 1: Jagiellonian U Contest, Tuesday, January 30, 2018 Problem A. XOR
题意:给你一些数,问你是否能够将它们划分成两个集合,使得这两个集合的异或和之差的绝对值最小. 设所有数的异或和为S,集合A的异或和为A. 首先,S的0的位对答案不造成影响. S的最高位1,所对应的A的 ...
- 【推导】【构造】Petrozavodsk Summer Training Camp 2015 Day 2: Xudyh (TooSimple) Contest, Saturday, August 22, 2015 Problem G. Travelling Salesman Problem
一个矩阵,每个位置有一个非负整数,一个人从左上走到右下,不能走重复的格子,问得到的最大权值. 当长宽不都为偶数时,必然能走遍所有格子,横着从左到右,从右到左(或是竖着走)走完即可. 当长宽都是偶数时, ...
- 2015 UESTC Winter Training #7【2010-2011 Petrozavodsk Winter Training Camp, Saratov State U Contest】
2015 UESTC Winter Training #7 2010-2011 Petrozavodsk Winter Training Camp, Saratov State U Contest 据 ...
随机推荐
- [转]ubuntu16.04~qt 5.8无法输入中文
编译fcitx-qt需要cmake,安装cmake命令,如果已经安装,请略过. sudo apt-get install cmake 安装 fcitx-libs-dev sudo apt-get in ...
- Strusts2笔记9--防止表单重复提交和注解开发
防止表单重复提交: 用户可能由于各种原因,对表单进行重复提交.Struts2中使用令牌机制防止表单自动提交.以下引用自北京动力节点:
- springboot中报异常Whitelabel Error Page
开始以为是url写错了,但其实不是,然后启动application类在的包是要在最顶部,并且和pom中groupid一样 这个也没错,后来发现能访问RestController中的url,但是进不了方 ...
- PATH变量重复
命令: export PATH=$(echo $PATH | tr : "\n"| sort | uniq | tr "\n" :) Code: awk -F: ...
- Pytorch自定义数据库
1)前言 虽然torchvision.datasets中已经封装了好多通用的数据集,但是我们在使用Pytorch做深度学习任务的时候,会面临着自定义数据库来满足自己的任务需要.如我们要训练一个人脸关键 ...
- 分别使用docx4j,jacob将文字与图片插入word中书签位置
项目中需要将一段文字,与人员的签名(图片)插入到上传的word中,上网查询了一下,有许多种方式可以向word中插入文字,发现docx4j与jacob都为比较常见的解决方案,于是就先使用的docx4j进 ...
- JS实现逼真的雪花飘落特效
逼真的雪花飘落特效 效果图: 图片素材 : --> ParticleSmoke.png 代码如下,复制即可使用: <!doctype html> <html> <h ...
- Git push将本地版本库的分支推送到远程服务器上对应的分支
在使用git commit命令将修改从暂存区提交到本地版本库后,只剩下最后一步将本地版本库的分支推送到远程服务器上对应的分支了,如果不清楚版本库的构成,可以查看我的另一篇,git 仓库的基本结构. g ...
- SQL Server 2000中查询表名,列名及字段类型
经常碰到一些忘记表名称的情况,此时只记得个大概,此时可通过查询系统表Sysobjects找到所要的表名,如要查找包含用户的表名,可通过以下SQL语句实现, Select * From sysobjec ...
- Linux学习笔记:pwd与dirs的区别
在Linux中可以使用pwd和dirs进行当前目录查看,分别用于显示当前目录和显示完整目录记录.具体如下: 1.pwd 显示当前目录 2.dirs 显示目录堆叠中的记录 END 2018-08-21 ...