首页 > 其他分享 >2015 ACM ICPC Singapore Regional D(折半枚举+二分)

2015 ACM ICPC Singapore Regional D(折半枚举+二分)

时间:2024-04-29 11:12:44浏览次数:23  
标签:折半 std Singapore int auto Regional fac diff prod

D - Association of Computer Maintenance

题意

给定至多350个小于100的质数,对于所有质数之积k将它分解为两个数a和b使得a*b=k。

输出最小的a+b,并对1e9+7取模

分析

首先考虑想如果想让a+b最小,即让abs(a-b)最小。

随后根据限制条件k的因子数不超过1e10,容易想到将k拆分成k1和k2,此时对于k1和k2的因子数都不超过1e5。
考虑将k1的所有因子存下,最后再枚举k2的所有因子去匹配最接近的k1因子,记录下最小值即可。时间复杂度O(1e5log(1e5))。这边注意维护因子时由于高精度过慢,考虑转换成对数比较大小。

代码实现

c

include <bits/stdc++.h>

int main() {
std::cin.tie(nullptr)->sync_with_stdio(false);
#define int long long
constexpr int P = 1e9 + 7;
std::string str;
std::cin >> str;
std::vector pri;
for (int i = 0; i < (int)str.size(); i += 2) {
pri.emplace_back((str[i] - '0') * 10 + (str[i + 1] - '0'));
}
std::sort(pri.begin(), pri.end());
std::vector<std::pair<int, int>> fac;
for (int i = 0; i < (int)pri.size(); ++i) {
int j = i + 1;
while (j < (int)pri.size() && pri[i] == pri[j]) j += 1;
fac.emplace_back(pri[i], j - i);
i = j - 1;
}
int pos = (int)fac.size() - 1;
for (int i = 0, j = 1; i < (int)fac.size(); ++i) {
if (j * (fac[i].second + 1) > 4e5) {
pos = i - 1;
break;
} else {
j *= fac[i].second + 1;
}
}
auto power = [&](int a, int b) {
int c = 1;
for (; b; b >>= 1, a = a * a % P)
if (b & 1) c = c * a % P;
return c;
};
std::vector<std::pair<int, int>> s;
std::vector<std::pair<double, int>> prod;
int idx = 0;
auto dfs = [&](auto &&self, int u, double diff, int s1, int s2) ->void {
if (u == pos + 1) {
prod.emplace_back(diff, idx++);
s.emplace_back(s1, s2);
return ;
}
auto [p, cnt] = fac[u];
for (int i = 0; i <= cnt; ++i) {
self(self, u + 1, diff + log(p) * (i + i - cnt), s1 * power(p, i) % P, s2 * power(p, cnt - i) % P);
}
};
dfs(dfs, 0, 0, 1, 1);
std::sort(prod.begin(), prod.end());
int ans = 0;
double max = 1e100;
auto find = [&](auto &&self, int u, double diff, int s1, int s2) ->void {
if (u == (int)fac.size()) {
int p = std::lower_bound(prod.begin(), prod.end(), std::pair<double, int>{-diff, -1}) - prod.begin();
if (p < (int)prod.size()) {
auto [w, id] = prod[p];
if (fabs(diff + w) < max) {
max = fabs(diff + w);
ans = (s1 * s[id].first % P + s2 * s[id].second % P) % P;
}
}
if (p - 1 >= 0) {
auto [w, id] = prod[p - 1];
if (fabs(diff + w) < max) {
max = fabs(diff + w);
ans = (s1 * s[id].first % P + s2 * s[id].second % P) % P;
}
}
return ;
}
auto [p, cnt] = fac[u];
for (int i = 0; i <= cnt; ++i) {
self(self, u + 1, diff + log(p) * (i + i - cnt), s1 * power(p, i) % P, s2 * power(p, cnt - i) % P);
}
};
find(find, pos + 1, 0, 1, 1);
std::cout << ans << '\n';
}

标签:折半,std,Singapore,int,auto,Regional,fac,diff,prod
From: https://www.cnblogs.com/sleeeeeping/p/18164285

相关文章

  • The 2018 ICPC Asia Qingdao Regional Programming Contest (The 1st Universal Cup,
    Preface久违地VP一场,虽然打的挺唐但勉强写出了8题前中期EFB三开三卡属实有点难受,而且B题这个套路大合集我和徐神两个人写了快200行也占用了一定机时但好在后面把卡住的题慢慢都写出来了,然后最后40min冲刺L题成功比较可惜的是I这个开场看的题没有再细想一步,感觉想到在线段树上D......
  • The 2023 ICPC Asia Jinan Regional Contest
    目录写在前面DIAG写在最后写在前面比赛地址:https://codeforces.com/gym/104901。以下按个人向难度排序。SUA的题确实牛逼,把我这种只会套路的沙比狠狠腐乳了。D签到。直接枚举\([L,\min(R,L+10)]\)检查即可。///*By:Luckyblock*/#include<bits/stdc++.h>#defi......
  • 折半搜索
    简介折半搜索是一种优化搜索的方法,一般可以将\(O(2^N)\)优化为\(O(2^{\frac{N}{2}})\)。其思想为将一个搜索拆分成两个搜索,分别处理前一半和后一半,使用map或vector等东西记录第一次搜索的信息,在第二次搜索时查询。如以下代码:voiddfs(intx,intsum){if(x>k){......
  • The 2022 ICPC Asia Xian Regional Contest / ICPC 西安 2022 (ABDHJKL)
    本文搬运自本人的知乎文章。https://zhuanlan.zhihu.com/p/588162564好久没有在补题之后写题解的习惯了。但是最近感觉有些题目的思路即使在题目通过后仍然难以理清,因此觉得需要写些东西帮助自己整理思路,另外也方便以后翻看积累到的技巧。J.StrangeSum题目链接Problem-J......
  • The 2022 ICPC Asia Xian Regional Contest
    The2022ICPCAsiaXianRegionalContestJ.StrangeSum题意:给定n个数,选定最多不超过两个数字的和的最大值思路:签到voidsolve(){lln;cin>>n;vector<ll>a(n+1);for(inti=1;i<=n;i++)cin>>a[i];llans=0;sort(a.begin()......
  • 折半搜索
    折半搜索折半一般可以把时间复杂度从\(O(2^{n})\)变成\(O(2^{n/2}\cdotn)\)。一般可以从初始状态搜一次,从目标状态搜一次。伪代码voiddfs1(intx,/*其他的状态*/){ if(x==mid+1){ /* 统计发案数 */ } dfs1(x+1,/*选第x个东西的代价*/); dfs1(x+......
  • The 2023 ICPC Asia Hong Kong Regional Programming Contest (The 1st Universal Cup
    Preface不知道VP什么就继续找往年的区域赛真题来打了这场题挺合我们队口味的,开场2h就开出了5题(徐神110min的时候就过相对最难的C题),而且手上还有3个会写的题最后中间虽然因为F题卡常(CF评测机太慢导致的)浪费了快1h时间,但索性时间剩余很多还是4h下班了后面的题感觉都不太可做,遂光......
  • The 2022 ICPC Asia Hangzhou Regional Programming Contest
    目录写在前面FDCKAGM写在最后写在前面比赛地址:https://codeforces.com/gym/104090。以下按个人难度向排序。最上强度的一集,然而金牌题过了铜牌题没过,唐!去年杭州似在一道树上痛失Au呃呃,vp2022树题过了然而铜牌题没过呃呃F签到。大力模拟。codebydztle:#include<bit......
  • The 2023 ICPC Asia Jinan Regional Contest (The 2nd Universal Cup. Stage 17: Jina
    The2023ICPCAsiaJinanRegionalContest(The2ndUniversalCup.Stage17:Jinan)D.LargestDigit题意:给定两个范围la,ra,lb,rb,求在两个范围内选任意两个数相加,求最大的数位思路:暴力枚举即可,遇到9跳出循环voidsolve(){llla,ra,lb,rb;cin>>la>>r......
  • 记录学生的姓名、编号以及总分,输入n,代表学生个数,要求用结构体泡排序将学生信息按学生
    //记录学生的姓名、编号以及总分,输入n,代表学生个数,要求用结构体,//用冒泡排序将学生信息按学生总分从低到高排名,将学生信息打印出来;//并输入一个总分x,用折半查找查找所有总分为x的学生,并将学生信息打印出来#include<stdio.h>#include<stdlib.h>structStudent{ ch......