等比数列三角形 (数论 + 黄金分割点)+ JOISC 2016 Day3 T3 「电报」(基环树 + 拓扑排序)

文章目录

  • T1:等比数列三角形
    • 题目
    • 题解
    • 代码实现
  • T2:电报
    • 题目
    • 题解
    • 代码实现

T1:等比数列三角形

题目

求三边都是 ≤n 的整数,且成等比数列的三角形个数
注意三角形面积不能为 0
注意 oeis 中未收录此数列,所以并不需要去搜了

输入格式
一行一个整数 n
输出格式
一行一个整数表示答案

样例
样例输入1
9
样例输出1
10
样例解释1
除去 9 个等边三角形,还有 {4,6,9} 。

样例输入2
100
样例输出2
133

数据范围与提示
一共有 4 个子任务,对于每一个子任务,你只有通过了该子任务的所有测试点,才能获得此子任务的分数
有 10pts,保证 n≤10
有 20pts,保证 n≤105
有 20pts,保证 n≤105
有 50pts,保证 n≤1012
对于所有数据,有1≤ n≤1012

题解

在这里插入图片描述
注意{4,6,9},{6,4,9},{9,6,4}算同一个三角形,所以不用管顺序
设三条边从小到大分别为a,ak,ak2a,ak,ak^2a,ak,ak2(kkk为公比且为正整数)
所以1≤k1≤k1k


就然要构成三角形,必然要满足
a+ak>ak2=>1+k>k2=>k2−k−1<0a+ak>ak^2=>1+k>k^2=>k^2-k-1<0a+ak>ak2=>1+k>k2=>k2k1<0
解得k<√5+12k<\frac{√5+1}{2}k<25+1

综上k∈[1,√5+12)k∈[1,\frac{√5+1}{2})k[1,25+1)


接下来令k=pqk=\frac{p}{q}k=qp(q,pq,pq,p互质),最大边就表示为a∗p2q2a*\frac{p^2}{q^2}aq2p2
最大边≤n≤nn,故此q≤√nq≤√nqn
因为q=pkq=\frac{p}{k}q=kp,那么

  • kkk取最大时,qqq取最小,把k=√5+12k=\frac{√5+1}{2}k=25+1带入就解出了qqq的最小值,
    但因为k取不到这个开区间,q的这个最小值也是一个开区间
  • 当k取最小时,qqq取最大,这是满足q=pq=pq=pqqq的这个最大值是一个闭区间

综上q∈(p∗2√5+1,p]q∈(p*\frac{2}{√5+1},p]q(p5+12,p],在这里有个转化思想,把ppp代换成qqq,得到q∈(q∗2√5+1,q]q∈(q*\frac{2}{√5+1},q]q(q5+12,q]
我们就可以枚举p∈[1,√n]p∈[1,√n]p[1,n],算出此时q的可取值个数
注意:其实理解成枚举qqq也是说得通的
在这里插入图片描述


当这样统计完后,会出现一个问题
{2,3,6},{4,6,9}\{2,3,6\},\{4,6,9\}{236},{469}这种公比为32\frac{3}{2}23的三角形,会被重复计算进公比为64\frac{6}{4}46
所以我们需要把这些排除掉,这也是为什么上面推导的时候pq\frac{p}{q}qp要保证互质
这里就可以用类似埃筛的方法,把xxx的因数里面算过的三角形减掉

要正着减,如果倒着,公比为128\frac{12}{8}812会先减掉公比为96\frac{9}{6}69而这里面还包含着32\frac{3}{2}23
会导致32\frac{3}{2}23被重复减掉


代码实现

#include <cstdio>
#include <cmath>
using namespace std;
#define LL long long
#define MAXN 1000005
LL n, result;
int ok[MAXN];
int main() {scanf ( "%lld", &n );int sqt = sqrt ( n );for ( int i = 1;i <= sqt;i ++ ) {int t = i * ( 2 / ( sqrt ( 5 ) + 1 ) );ok[i] = i - t;}for ( LL i = 1;i <= sqt;i ++ )for ( LL j = i << 1;j <= sqt;j += i )ok[j] -= ok[i];for ( LL i = 1;i * i <= n;i ++ )result += ( n / ( i * i ) ) * ok[i];printf ( "%lld", result );return 0;
}

T2:电报

题目

给出 n 个点,每个点的出度均为 1,给出这 n 个点初始指向的点A[i] ,和改变这个点指向的目标所需要的价值 C[i]。
求让所有点强连通的最小花费。

输入格式
第一行输入一个数 n 表示点的个数。
之后的 n 行每行两个数 A[i],C[i] 表示第 i 个点指向第 A[i] 个点,更改该点指向的点花费为 C[i]。
输出格式
共一行,为让所有点强连通的最小花费。

样例
样例输入 1
4
2 2
1 4
1 3
3 1
样例输出 1
4
样例解释 1
在这里插入图片描述
很显然,把 1–>2 的这条边改成 (花费 4)的情况下构成强连通分量花费最小。

样例输入 2
4
2 2
1 6
1 3
3 1
样例输出 2
5
样例解释 2
很显然把 1–>2 的这条边改成 1–>4 花费 2,把 3–>1 的这条边改成 3–>2 花费 3 的情况下构成强连通分量花费最小,总花费为 5。

样例输入 3
4
2 2
1 3
4 2
3 3
样例输出 3
4

样例输入 4
3
2 1
3 1
1 1
样例输出 4
0
在这里插入图片描述

题解

在这里插入图片描述
首先为了能变成强连通,树上的点彼此之间需要破掉,先不动环上的点

如图中:7,8,97,8,978910,11,12,1310,11,12,1310111213就必须破掉,破成一条链

要么把7→87\rightarrow878破掉,要么把7→97\rightarrow979破掉,然后让7−8−97-8-9789连成一条链

可以用拓扑排序找到不是环上的点,然后把这棵树破成链,如果本身是链就不进行操作

图就变成多个环和多棵树的形态

显然,环彼此之间是相互独立的,就可以扫一次先处理出所有的环

我们在上面进行树上破成链的时候,把环延伸的链或树也一起破掉

如图中:就把6→76\rightarrow7676→106\rightarrow10610都给破掉

接着如果变成强连通,环与环之间必须相互有路去连通

就是复活环与之外连的某一条边

意味着我们要把环破掉一条边和外界相连
在这里插入图片描述
那么这个时候,对于环上的最佳答案点肯定满足把它与它父亲在环上的边破掉,然后把它与自己延伸的链的点进行相连的操作花费最小

破环就是自己的CCC值,与链上的点保留一条边,就是找链上点的CCC的最大值

如图中:我们要把6→16\rightarrow161破掉,复活6→76\rightarrow767或者6→106\rightarrow10610任意一条边

而且必须复活至少一条,这样才能让环与外面进行连通

但是如果图上有多个点的复活值是负数,那么肯定是全选上,使答案变得更小

在上面破 环与链的边 的时候,我们就记录最大值的CCC,复活的时候,肯定复活这一条边,其他边的消耗远小于这一条边破掉的消耗


最后我们来解释一下代码的一些地方,旁边的小姐姐问了我很久

  • 为什么是建反图:
    想一想,如果我们建正图,每个点都只会有一个指向点,即每个点的vector里面都只有111个点,怎么破链,复活等以上的操作呢?
    换言之,每个点要知道自己的后继,才能知道破哪些边

  • flag||tot>1的问题,我们要知道
    当只有环的时候,如果环是多个,也需要破掉,使所有环彼此强连通
    当只有一个环的时候,如果环上有链也需要破掉,不然环上的点无法走到链上的点
    所以这里是取或,当且仅当原图本身就是一个环才不用考虑复活


在这里插入图片描述

代码实现

这里定义isCircle[i]
1:表示这个点不在环上(PS:可能误导了许多亲故 )
2:表示这个点在环上且已经经过了破树或破链处理
0:表示这个点在环上但等待被处理

#include <queue>
#include <cstdio>
#include <vector>
#include <cstring>
#include <iostream>
using namespace std;
#define MAXN 100005
queue < int > q;
vector < int > G[MAXN], circle[MAXN];
int n, tot;
bool flag;
int a[MAXN], c[MAXN];
int d[MAXN], g[MAXN], isCircle[MAXN];
long long result;int main() {scanf ( "%d", &n );for ( int i = 1;i <= n;i ++ ) {scanf ( "%d %d", &a[i], &c[i] );G[a[i]].push_back ( i );d[a[i]] ++;}for ( int i = 1;i <= n;i ++ )if ( ! d[i] ) {q.push ( i );isCircle[i] = 1;flag = 1;}while ( ! q.empty() ) {int t = q.front();q.pop();d[a[t]] --;if ( ! d[a[t]] ) {q.push ( a[t] );isCircle[a[t]] = 1;}}for ( int i = 1;i <= n;i ++ ) {if ( isCircle[i] == 1 ) {//破树为链int Max = 0;for ( int j = 0;j < G[i].size();j ++ ) {Max = max ( Max, c[G[i][j]] );result += c[G[i][j]];}result -= Max;}else {for ( int j = 0;j < G[i].size();j ++ )if ( isCircle[G[i][j]] == 1 ) {//破环与外面延伸的链g[i] = max ( g[i], c[G[i][j]] );//记录一条链的最大值result += c[G[i][j]];}if ( isCircle[i] == 0 )tot ++;int x = i;while ( isCircle[x] == 0 ) {//分离出环isCircle[x] = 2;circle[tot].push_back ( x );x = a[x];}}}if ( flag || tot > 1 ) {for ( int i = 1;i <= tot;i ++ ) {int Min = 0x3f3f3f3f;for ( int j = 0;j < circle[i].size();j ++ )//复活Min = min ( Min, c[circle[i][j]] - g[a[circle[i][j]]] );if ( Min >= 0 )//必须复活的一条边result += Min;else {for ( int j = 0;j < circle[i].size();j ++ )if ( c[circle[i][j]] - g[a[circle[i][j]]] < 0 )//可多复活几条边result += c[circle[i][j]] - g[a[circle[i][j]]];//破掉i与fi的环上边的时候,接的那一条边肯定是接在fi上}}}printf ( "%lld", result );return 0;
}

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/318177.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

模板:笛卡尔树

介绍 笛卡尔树是一种非常特殊的二叉搜索树。每个节点有两个信息x和y。如果只考虑 x&#xff0c;它是一棵二叉搜索树&#xff0c;如果只考虑 y&#xff0c;它是一个小根堆。 实现 按照y升序插入 显然应该插入到一条极右链上 但为了维护x二叉搜索树的性质 对于右链上x>当前…

乱搞

占个坑&#xff0c;找时间补

【AcWing 243. 一个简单的整数问题2】

例题&#xff1a;【AcWing 243. 一个简单的整数问题2】 线段树模板题&#xff0c;区间修改区间求和。 题解&#xff1a; 将序列分成N/B块&#xff0c;维护&#xff1a; id[i] i/B&#xff0c;i所在块标号 res[id] 第id块的sum base[id] 第id块的add标记修改时&#xff0…

CF1540B-Tree Array【数学期望,dp】

正题 题目链接:https://www.luogu.com.cn/problem/CF1540B 题目大意 nnn个点的一棵树&#xff0c;开始随机选择一个点标记&#xff0c;然后每次随机选择一个与被标记点连边的点标记&#xff0c;按照标记顺序排列&#xff0c;求期望逆序对数。 1≤n≤2001\leq n\leq 2001≤n≤2…

使用PerfView监测.NET程序性能(三):分组

在上一篇博客使用PerfView监测.NET程序性能&#xff08;二&#xff09;&#xff1a;Perfview的使用中&#xff0c;我们通过Perfview帮助文件中自带的代码来简单使用了Perfview&#xff0c;了解了基本操作。现在来看看Perfview中的分组操作&#xff08;Grouping&#xff09;。分…

【做题记录】构造题

CF468C Hack it! 题意&#xff1a; 令 \(F(x)\) 表示 \(x\) 的各个位上的数字之和&#xff0c;如 \(F(1234)123410\) 。 给定 \(a(a\le 10^{18})\) &#xff0c;请求出任意一组 \(l,r(l,r\le 10^{200})\) &#xff0c;要求满足&#xff1a; \[\sum_{il}^{r}F(i)\pmod{a}0 \]输出…

主席树 学习报告

文章目录前言可持久化线段树代码区间第k大代码练习粟粟的书架代码森林代码任务查询系统代码列队代码前言 主席树&#xff0c;全称是可持久化权值线段树 利用r和l-1两棵权值线段树作差得到[l,r]的信息 从而解决各种问题 在排名这方面功能极其强大 可持久化线段树 学主席树之前…

Star Way To Heaven (prim最小生成树) // [ NOIP提高组 2014]飞扬的小鸟(DP)

文章目录T1&#xff1a;Star Way To Heaven题目题解代码实现T2&#xff1a;飞扬的小鸟题目题解代码实现T1&#xff1a;Star Way To Heaven 题目 小 w 伤心的走上了 Star way to heaven。 到天堂的道路是一个笛卡尔坐标系上一个 n*m 的长方形通道 顶点在 (0,0) 和 (n,m) 。 小…

CF1043E Train Hard, Win Easy

CF1043E Train Hard, Win Easy 题意&#xff1a; n个人有Ai和Bi两个属性&#xff0c;给出m个关系&#xff1a;xi yi表示xi和yi不能配对 i,j两人规定匹配的价值为min (Ai Bj , Bi Aj ) 回答出每个人跟所有人配对&#xff08;除开不能和自己匹配的人&#xff09;的价值总和 …

P7887-「MCOI-06」Existence of Truth【构造】

正题 题目连接:https://www.luogu.com.cn/problem/P7887?contestId52021 题目大意 给出三个长度为nnn的序列xi,yi,zix_i,y_i,z_ixi​,yi​,zi​&#xff0c;求一个序列aaa满足0≤ai<10970\leq a_i<10^970≤ai​<1097且 xi(∑j1iaj)yi(∑jinaj)≡zi(mod1097)x_i\lef…

IdentityServer4-客户端的授权模式原理分析(三)

在学习其他应用场景前&#xff0c;需要了解几个客户端的授权模式。首先了解下本节使用的几个名词Resource Owner&#xff1a;资源拥有者&#xff0c;文中称“user”&#xff1b;Client为第三方客户端&#xff1b;Authorization server为授权服务器&#xff1b;redirection URI&…

【做题记录】[NOIP2011 提高组] 观光公交

P1315 [NOIP2011 提高组] 观光公交 我们想在 \(k\) 次加速每一次都取当前最优的方案加速。 考虑怎样计算对于每一条边如果在当前情况下使用加速器能够使答案减少的大小。 如果当前到达某个点时已经有人在等待了&#xff0c;那么加速这个点以前的边能够让这个点下车的人距离减少…

[2019 牛客CSP-S提高组赛前集训营4题解] 复读数组(数论)+ 路径计数机(数上DP)+ 排列计数机(线段树+二项式定理)

文章目录T1&#xff1a;复读数组题目题解代码实现T2&#xff1a;路径计数机题目题解代码实现T3&#xff1a;排列计数机题目题解CODET1&#xff1a;复读数组 题目 有一个长为nk的数组&#xff0c;它是由长为n的数组A1,A2,…,An重复k次得到的。 定义这个数组的一个区间的权值为…

模板:(多重)哈希

前言 还在为不想写双哈希又怕哈希冲突挂掉发愁吗&#xff1f; 来这里&#xff0c;满足你的一切梦想&#xff01; 哈希还有模板&#xff1f; 其实就是把相关的函数和数组打包到一个结构体里 但是针心方便啊&#xff01;&#xff01;&#xff01; 如果想双哈希的话&#xff0c;定…

CF1183H Subsequences (hard version)

题意&#xff1a; 长度为n的字符串S&#xff0c;现在要找出k个不同的子序列&#xff0c;使得这些序列的总价值最低 一个序列的价值等于删去的字符长度&#xff08;空串也算子序列&#xff09; 1≤n≤100,1≤k≤1012 题解&#xff1a; 一看就是dp&#xff0c;我们先想想串a可…

P7888-「MCOI-06」Distinct Subsequences【dp】

正题 题目大意 给出一个长度为nnn的字符串aaa&#xff0c;求它的所有子序列的本质不同子序列个数。 1≤n≤1061\leq n\leq 10^61≤n≤106 解题思路 考虑每个子序列产生的贡献&#xff0c;为了防止算重我们一个只统计走子序列自动机上的边的子序列&#xff0c;也就是说对于TTT…

微软携手 Docker 打造 CNAB,分布式应用来了!

微软中国MSDN 前天Microsoft Connect(); 2018发布的众多最新科技&#xff0c;都让全球开发者惊艳不已。其中一项最令开发者瞩目并迫不及待——微软联合Docker发布了云本地应用捆绑包&#xff08;Cloud Native Application Bundle&#xff0c;以下简称CNAB&#xff09;&#xff…

9.4 模拟

前言 175分 60100150 T3和T4做的不好 T4没有理解题目的意思…qwq T3暴力似乎挂了… 但T1和T2还是不戳的 T1打表找规律的方法也许更为有效 考场 先看题。 药丸。。 T3、4甚至根本没有看懂… T1和T2也感觉挺玄乎的 有一种爆零的预感 8&#xff1a;10 先看T1 推了推似乎还是有…

P4135 作诗

P4135 作诗 题意&#xff1a; 给定 n 个不大于 c 的正整数 a1…an 和 m 组询问&#xff0c;每次问 [l,r] 中有多少个数出现正偶数次。 对于每次询问&#xff1a; 设上一个询问的答案为 ans&#xff08;第一个询问时 ans0&#xff09;&#xff0c;令L(lans)mod n1&#xff0c;…

[C++]试一试结构体struct node的构造函数

可直接点击跳转到构造函数处结构体概念定义结构体定义结构体及结构体变量结构体变量的特点成员调用成员函数调用结构体的构造函数Upd1Upd2Upd3结构体概念 在实际问题中&#xff0c;一组数据往往具有不同的数据类型。 例如&#xff1a;人口大普查时&#xff0c;需要记录每一个人…