【取对数】【哈希】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 据 ...
随机推荐
- SpringCloud之Eureka(注册中心集群篇)
一:集群环境搭建 第一步:我们新建两个注册中心工程一个叫eureka_register_service_master,另一个叫eureka_register_service_backup eureka ...
- D. GCD Counting(树上dp)
题目链接:http://codeforces.com/contest/1101/problem/D 题目大意:给你n个点,每个点都有权值,然后给你边的关系,问你树上的最大距离.(这里的最大距离指的是这 ...
- imperva-指定url禁止访问
指定url禁止访问 应用到那个网站 访问一下查看告警
- 邮件伪造测试-Swaks
1. 前言 在kali中自带一个邮件伪造工具Swaks,工具项目主页为 http://jetmore.org/john/code/swaks 2.基本用法: swaks --to --from --e ...
- Dummynet模拟高时延网络场景(Windows7)
如果安装时出现:my_socket failed 2, cannot talk to kernel module 请查看是否以管理员方式运行,如果是,再判断当前操作系统是否为Win7 64位,如果是, ...
- iptables详细设置
1.安装iptables防火墙 怎么知道系统是否安装了iptables?执行iptables -V,如果显示如: iptables v1.3.5 说明已经安装了iptables. 如果没有安装ipta ...
- Runtime - 消息发送原理
Runtime - 消息发送原理. Objective-C运行时的核心就在于消息分派器objc_msgSend,消息分派器把选择器映射为函数指针,并调用被引用的函数. 要想理解objc_msgSend ...
- 【Android开发】之Fragment开发1
一直知道Fragment很强大,但是一直都没有去学习,现在有些空闲的时间,所以就去学习了一下Fragment的简单入门.我也会把自己的学习过程写下来,如果有什么不足的地方希望大牛指正,共同进步! 一. ...
- 【小程序开发】购物车加减几件demo
<!-- 主容器 --> <view class="stepper"> <!-- 减号 --> <text class="{{m ...
- Python_oldboy_自动化运维之路_函数,装饰器,模块,包(六)
本节内容 上节内容回顾(函数) 装饰器 模块 包 1.上节内容回顾(函数) 函数 1.为什么要用函数? 使用函数之模块化程序设计,定义一个函数就相当于定义了一个工具,需要用的话直接拿过来调用.不使用模 ...