【取对数】【哈希】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 据 ...
随机推荐
- 谈谈Linux内核驱动的coding style【转】
转自:http://www.cnblogs.com/wwang/archive/2011/02/24/1960283.html 最近在向Linux内核提交一些驱动程序,在提交的过程中,发现自己的代码离 ...
- 个性化你的Git Log的输出格式
git已经变成了很多程序员日常工具之一. git log是查看git历史的好工具,不过默认的格式并不是特别的直观. 很多时候想要更简便的输出更多或者更少的信息,这里列出几个git log的format ...
- axios通过django的csrf验证
django会在浏览器的cookie里面保存一项csrftoken=GvzB3ilhlgadishmascacsilreclherlkjhaklsdv3qx4M96XRG88omScDPQaKoMxJ ...
- unity 2d 游戏优化之路 遇坑记录
情景说明: unity 出的Android包,在目前一些主流机型跑都没有问题,但是在 小米3 这种比较老的机器上跑,报如下错误 GLSL compilation failed, no infolog ...
- dede导航栏目调用
1.基础调用 {dede:channel row='5' type ='top' } <li><a href="[field:typelink/]">[fi ...
- opencv(4)实现数据增加小工具
数据增加(data augmentation),作为一种深度学习中的常用手段,数据增加对模型的泛化性和准确性都有帮助.数据增加的具体使用方式一般有两种,一种是实时增加,比如在Caffe中加入数据扰动层 ...
- 教您如何进行SQL跨表更新
SQL跨表更新数据是在使用SQL数据库中比较常用的,下面就将为您详细介绍SQL跨表更新数据的步骤,希望对您学习SQL跨表更新数据有所启迪. 原始数据如下,首先是表结构 A_dept的初始数据 A_em ...
- Jmeter的接口测试简介
一.安装Jmeter Jmeter官方首页:http://jmeter.apache. ...
- CentOS下编译安装python包管理安装工具pip教程
ubuntu 安装pip 代码如下: apt-get install python-pip 安装requests, pip install requests 对于centos的,直接 yum inst ...
- JavaSE简单实现多线程聊天
1.1 主程序入口 在主程序入口处,通过设置MyWindow的第一个参数,如果为true则为服务器,如果为false,则为客户端,当然也可以设置第二个参数,区分客户端和服务器的窗口标题. public ...