首页 > 其他分享 >Pictionary 方法记录

Pictionary 方法记录

时间:2022-11-01 00:00:33浏览次数:78  
标签:Pictionary 记录 int 城市 样例 roads cities 方法 day

[COCI2017-2018#5] Pictionary

题面翻译

题目描述

在宇宙一个不为人知的地方,有一个星球,上面有一个国家,只有数学家居住。
在这个国家有\(n\)个数学家,有趣的是,每个数学家都住在自己的城市,且城市间无道路相连,因为他们可以在线交流。当然,城市有从\(1\)到\(n\)的编号。

一位数学家决定用手机发论文,而手机将“不言而喻”自动更正成了“猜谜游戏”。
不久之后,这个国家就发现了猜谜游戏。他们想要见面一起玩,于是这个国家就开始了修路工程。
道路修建会持续\(m\)天。对于第\(i\)天,若\(\gcd(a,b)=m-i+1\),则\(a\)和\(b\)城市间会修一条路。

由于数学家们忙于建筑工作,请你来确定一对数学家最早什么时候能凑到一起玩。

输入输出格式

输入格式

第一行有三个正整数\(n,m,q\),表示城市数量、修路持续天数、询问数量。
接下来\(q\)行,每行有两个正整数\(a,b\),表示询问\(a\)和\(b\)两个城市的数学家最早什么时候能在一起玩。

输出格式

输出\(q\)行,第\(i\)行有一个正整数,表示第\(i\)次询问的结果

说明

数据范围:
对于\(40\%\)的数据:
\(n≤4000,q≤10^5\)
对于全部数据:
\(1≤n,q≤10^5\)
\(1≤m≤n\)

样例1解释:
在第一天,\((3,6)\)之间修了一条路,因此第二次询问输出1
在第二天,\((2,4),(2,6),(2,8),(4,6),(6,8)\)之间都修了一条路,此时\(4\)和\(8\)号城市连通,第三次询问输出2
在第三天,所有编号互质的城市之间都修了路,\(2\)和\(5\)号城市在此时连通,第一次询问输出1

样例2解释:
在第二天,\((20,15)\)之间修了一条路
第四天,\((15,9)\)之间修了一条路
所以\(20\)和\(9\)号城市在第四天连通,输出4

题目描述

There is a planet, in a yet undiscovered part of the universe, with a country inhabited solely
by mathematicians. In this country, there are a total of ​N mathematicians, and the interesting
fact is that each mathematician lives in their own city. Is it also interesting that no two cities
are connected with a road, because mathematicians can communicate online or by
reviewing academic papers. Naturally, the cities are labeled with numbers from 1 to ​N.

Life was perfect until one mathematician decided to write an academic paper on their
smartphone. The smartphone auto-corrected the word “self-evident” to “Pictionary” and the
paper was published as such. Soon after, the entire country discovered pictionary and
wanted to meet up and play, so construction work on roads between cities began shortly.
.
The road construction will last a total of ​M days, according to the following schedule: on the
first day, construction is done on roads between all pairs of cities that have ​M as their
greatest common divisor. On the second day, construction is done on roads between all
pairs of cities that have ​M-1 as their greatest common divisor, and so on until the ​\(M^{th}\) day
when construction is done on roads between all pairs of cities that are co-prime. More
formally, on the \(i^{th}\) day, construction is done on roads between cities ​a and ​b if ​gcd(a, b) = \(M-i+1\).

Since the mathematicians are busy with construction work, they’ve asked you to help them
determine the minimal number of days before a given pair of mathematicians can play
pictionary together.

输入格式

The first line of input contains three positive integers ​N, M
and ​Q
(1 ≤ ​N
, ​Q ≤ 100 000, 1 ≤ ​M
≤ ​N
), the number of cities, the number of days it takes to build the roads, and the number of
queries.

Each of the following ​Q lines contains two distinct positive integers ​A and ​B
(1 ≤ ​A
, ​B ≤ ​N
)
that denote the cities of the mathematicians who want to find out the minimal number of days
before they can play pictionary together.

输出格式

The \(i^{th}\) line must contain the minimal number of days before the mathematicians from the \(i^{th}\) query can play pictionary together.

样例 #1

样例输入 #1

8 3 3
2 5
3 6
4 8

样例输出 #1

3
1
2

样例 #2

样例输入 #2

25 6 1
20 9

样例输出 #2

4

样例 #3

样例输入 #3

9999 2222 2
1025 2405
3154 8949

样例输出 #3

1980
2160

提示

In test cases worth 40% of total points, it will hold ​N
≤ 1000, ​Q
≤ 100 000.

Clarification of the first test case:

On the first day, road (3, 6) is built. Therefore the answer to the second query is 1.

On the second day, roads (2, 4), (2, 6), (2, 8), (4, 6) and (6, 8) are built. Cities 4 and 8 are now
connected (it is possible to get from the first to the second using city 6).

On the third day, roads between relatively prime cities are built, so cities 2 and 5 are connected.

Clarification of the second test case:

On the second day, road (20, 15) is built, whereas on the fourth day, road (15, 9) is built. After the
fourth day, cities 20 and 9 are connected via city 15.

审题

题意转化:

有\(n\)座城市;
有\(m\)个时刻,在第\(i\)个时刻,所有\(m-i+1\)的倍数之间连边;
有\(q\)个询问,询问第\(x_i\)座城市和第\(y_i\)座城市什么时候连通。

连边(合并)

连通城市的过程,其实就是对多个点建立集合,并进行合并的过程,所以考虑使用并查集

在对两个城市进行连边(即合并两个点)时,钦定第一个城市是第二个城市的父亲节点,并记录这两个点合并时的时间戳。

查询

现询问两个点\((x,y)\)的最早连通时间。\((x,y)\)的最早连通时间就是\(x\)到\(lca(x,y)\)中的最大时间戳加上\(lca(x,y)\)到\(y\)中的最大时间戳。

为什么是最大值?
两个城市要想连通,就必须要等到路径上最后一条边建好才行。

为什么是\(lca\)?
题目中城市\(x\)和城市\(y\)的连通抽象到图上就是\(x\)到\(y\)的一条树上路径(同一条边不能重复走),也就是\(x\)->\(lca(x,y)\)->\(y\).这里不能包含\(lca(x,y)\),因为这个点储存的时间戳是和另一个点击合并的时间。

考虑\(lca\)的求法。在处理并查集的时候,其实就处理出的图上的每一个父子关系,我们可以将其利用起来:根据这些父子关系,\(x\)和\(y\)往上跳,从而找到\(lca(x,y)\).

但要想保存父子关系就不能使用路径压缩,所以采用启发式合并:将小集合合并到大集合,以起到优化的作用。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm> 
using namespace std;
const int N=100010;
int n,m,q;
int f[N],siz[N],dfn[N],dep[N]; 
struct Edge//链式前向星存图 
{
	int u,v,nex;
}e[N<<1];
int head[N],tot;
void add(int u,int v)
{
	tot++;
	e[tot].u=u;
	e[tot].v=v;
	e[tot].nex=head[u];
	head[u]=tot;
}
int maxx(int a,int b)
{
	return a>b?a:b;
}
int find(int x)//并查集查找(不能用路径压缩) 
{
	if(x==f[x]) return x;
	return find(f[x]);
}
void dfs(int u)//dfs求每个点相对于超级祖先的深度 
{
	for(int i=head[u];i;i=e[i].nex)
	{
		int v=e[i].v;
		dep[v]=dep[u]+1;
		dfs(v);
	}
}
int main()
{
	scanf("%d%d%d",&n,&m,&q);
	int rt;
	for(int i=1;i<=n;i++)
	{
		f[i]=i;
		siz[i]=0;
	}
	for(int i=m;i>=1;i--)
	{
		for(int j=(i<<1);j<=n;j+=i)//对所有m-i+1的倍数之间连边 
		{
			int dx=find(i),dy=find(j);
			if(dx==dy)
			{
				continue;
			}
			if(siz[dx]<siz[dy])//启发式合并,将小集合合并到大集合 
			{
				swap(dx,dy);
			}
			f[dy]=dx;
			add(dx,dy);
			rt=dx;//rt最终会记录所有点的公共祖先,钦定这个“超级祖先”为根节点 
			if(siz[dx]==siz[dy])
			{
				siz[dx]++;
			}
			dfn[dy]=m-i+1;//dfn记录合并时的时间戳 
		}
	}
	dfs(rt);
	for(int i=1;i<=q;i++)
	{
		int x,y;
		scanf("%d%d",&x,&y);
		int ans=0;
		if(dep[x]<dep[y])
		{
			swap(x,y);
		}
		while(dep[x]>dep[y])
		{
			ans=maxx(ans,dfn[x]);
			x=f[x];
		}
		while(x!=y)
		{
			ans=maxx(maxx(dfn[x],dfn[y]),ans);
			x=f[x],y=f[y];
		}
		printf("%d\n",ans);
	}
}

参考

标签:Pictionary,记录,int,城市,样例,roads,cities,方法,day
From: https://www.cnblogs.com/fish4174/p/16846368.html

相关文章

  • Keil历史版本的几种下载方法
    Keil历史版本的几种下载方法MDKlegacyC51keil简单介绍官网正规步骤下载网址直接下载1.KeilMDK有规律的下载地址2.KeilC51有规律的下载地址3.KeilC251有规律的下载地址4......
  • LeetCode刷题记录.Day2
    移除元素题目链接 27.移除元素-力扣(LeetCode)classSolution{public:intremoveElement(vector<int>&nums,intval){intslotIndex=0;......
  • 伪分布示例解决方法
    产生问题如下:JAVA_HOME不存在,解决方法:vim/usr/local/hadoop/etc/hadoop/hadoop-env.sh中将JAVA_HOME与HADOOP_HOME进行填充,显示如下:此解决方案的依据是如下: ......
  • MATLAB约束最优化之罚函数法、障碍函数法和SQP方法
    1.罚函数法罚函数方法包括外点法和内点法。外点法又叫外罚函数法,顾名思义,迭代点再约束条件的可行域之外,既用于不等式约束又可用于等式约束。同样地,罚函数方法又叫序列无......
  • SpringCloudAlibaba 主要组件与nacos 填坑记录
    SpringCloudAlibaba主要功能与实现组件(1)SpringCloudAlibaba主要功能与实现组件【功能与实现组件:】服务限流降级:基本说明:默认支持WebServlet、WebF......
  • 下载官方Windows10最新系统镜像方法
    在微软官方网站同样也提供着Windows系统文件的下载,但在他的默认系统下载界面只提供了升级工具下载和媒体创建工具的下载,我们想要获取到系统的镜像文件还需要先下载媒体创建......
  • 类方法
    classBookStore:def__init__(self,bookname,bookcount):self.bookname=booknameself.bookcount=bookcountdefshell(self):s......
  • Programiranje 方法记录
    [COCI2017-2018#3]Programiranje题面翻译题目描述LittleLeticija正在准备编程考试。虽然她已经解决了很多任务,但还有一个任务尚未解决,所以她正在向你寻求帮助。您将获......
  • [单片机][N76E003][MCP4017][MCP4018][MCP4019] 数字电位器 使用方法 例子 代码
    7位:电阻分辨率-127电阻器(128步)-->W/*-----------------------------------------宏定义-----------------------------------------*//*------------------------------......
  • Mac应用程序无法打开或文件损坏的处理方法
    打开任何来源若没有“任何来源”这个选项,按以下步骤执行:1、打开终端(Terminal.app)2、拷贝粘贴sudospctl--master-disable按回车键3、输入你的账户密码,按回车键确认执......