首页 > 其他分享 >AT_arc060_c题解

AT_arc060_c题解

时间:2024-01-15 22:22:08浏览次数:24  
标签:int 题解 100005 fa arc060 nt 节点

纪念模拟考考挂。

思路

首先二分查找出当前点往后走最远能去哪个点,当前点为 \(i\),记最远能去的那个点为 \(nt_i\)。

考虑建一棵树,将 \(nt_i\) 设为 \(i\) 点的父节点。

暴力的话直接从当前点往上找,找到目标节点看几次就好了。

但显然是过不了的。

考虑使用倍增优化。

设 \(g_{i,j}\) 为从 \(i\) 往上跳 \(2^j\) 次能到达哪个点,这个可以预处理。每次往上跳时,如果当前节点为 \(nw\),则跳到 \(g_{nw,j}\),\(j\) 为当前指数,再将答案加上 \(2^j\),然后能跳则跳,如果到了目标节点就可以退出了。整体类似求最近公共祖先。

注意

  • 请记住,如果查找结束后并没有到目标节点,一定要将答案加上 \(1\)。不然会和我一样。

AC CODE

希望这篇题解可以帮助到你。

#include<bits/stdc++.h>
using namespace std;
int n,f,a[100005],nt[100005],q,g[100005][22],dep[100005];
vector<int>e[100005];
void dfs(int u,int fa){
	dep[u]=dep[fa]+1;
	g[u][0]=fa;
	for(int j=1;(1<<j)<=dep[u];j++){
		g[u][j]=g[g[u][j-1]][j-1];
	}
	for(auto v:e[u]){
		if(v!=fa)dfs(v,u);
	}
} 
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		scanf("%d",a+i);
	}
	scanf("%d",&f);
	for(int i=1;i<=n-1;i++){
		int l=i,r=n,pos=0;
		while(l<=r){
			int mid=l+r>>1;
			if(a[mid]<=a[i]+f){
				pos=mid;
				l=mid+1;
			}
			else {
				r=mid-1;
			}
		}
		nt[i]=pos;
	}
	for(int i=1;i<=n;i++){
		if(nt[i]!=i){
			e[nt[i]].push_back(i);
			e[i].push_back(nt[i]);
		}
	}
	dep[n+1]=-2;
	memset(g,0x3f,sizeof g);
	dfs(0,n+1);
	scanf("%d",&q);
	while(q--){
		int a,b;
		scanf("%d%d",&a,&b);
		if(a>b)swap(a,b);
		long long cnt=0;
		int now=a;
		for(int j=20;j>=0;j--){
			if((1<<j)<=dep[now]&&g[now][j]<=b){
				now=g[now][j];
				cnt+=(1<<j);
				if(now==b)break;
			}
		}
		if(now!=b)cnt++;//一定要加这句话,如果当前节点还没到,那么就要再多一天。
		printf("%lld\n",cnt);
	}
	return 0;
}

标签:int,题解,100005,fa,arc060,nt,节点
From: https://www.cnblogs.com/xdh2012/p/17966545

相关文章

  • 1.15模拟赛 T2题解
    简要题意多重背包但是乘法思路暴力就直接跑背包考虑乘法能否变为加法,可以找到模数的原根,将每个数映射一下,这样乘法就变成了加法,可以直接\(\text{bitset}\)优化,但是暴力这样做还是过不了于是我们考虑二进制分组优化背包,这样复杂度貌似就对了?code#pragmaGCCoptimize("Ofast......
  • border设置渐变boder-radius不生效问题解决方案
    <!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"/><metahttp-equiv="X-UA-Compatible"content="IE=edge"/><metaname="viewport"c......
  • 【题解】gym103743 (2022 JSCPC)
    A.PENTAKILL!考虑直接模拟,规则就是一个人将其他人全部都击杀,并且中间没有重复击杀。code:#include<bits/stdc++.h>usingnamespacestd;map<string,vector<string>>st;intn;stringa,b;intmain(){cin>>n;for(inti=1;i<=n;++i){ci......
  • 题解「JOI 2014 Final」IOI 馒头
    传送门。题意有\(n\)个物品,\(m\)个背包。第\(i\)个物品的价值是\(P_i\),第\(j\)个背包可以装\(C_i\)个物品,但会消耗\(E_i\)的价值。背包不能重复买,问最多可以获得多少价值。分析首先一个简单的贪心,我们在购买背包后塞入物品,一定时从大往小塞,也就是说,我们可以先对......
  • abc336 E - Digit Sum Divisible 题解 数位DP
    题目链接:https://atcoder.jp/contests/abc336/tasks/abc336_e题目大意:我们定义一个整数\(n\)的数位和为\(n\)的十进制表示中的各位上的数字之和。比如:整数\(2024\)的数位和为\(2+0+2+4=8\)。一个正整数\(n\)被称作一个好数如果\(n\)能被它的数位和整除......
  • CF1818B ndivisible 题解
    题意简述构造一个长度为\(n\)的排列\(A\),使得对于任意的\(l,r\)(\(1\lel<r\len\))都满足\(A_l+A_{l+1}+⋯+A_r\)不可以被\(r-l+1\)整除。输出其中一种合法排列即可。解题思路构造题。考虑对\(n\)进行分类讨论:当\(n=1\)时,由样例即可得合法排列为\(1\)......
  • P6021 洪水 题解
    请先完成ddp模板一个ddp讲解视频Part0:题意解释感觉题面太阴间了。所以解释一下:Cxt表示把\(x\)结点的权值改为\(t\).Qx:把\(x\)子树中一些结点删去,使得\(x\)与\(x\)子树内所有叶子结点不连通。求删去的结点权值和的最小值。Part1:先不考虑修改操作发现原......
  • electron安装卡住问题解决
    问题安装electron会卡住,你换镜像,挂梯子都没有用。解决办法自己配置下载electron二进制文件的地址解决步骤npmconfigls进入该配置文件,手动添加ELECTRON_MIRROR=https://npmmirror.com/mirrors/electron/electron_mirror=npm.taobao.org这两行重新npminstallele......
  • Codeforces Round 919 (Div. 2)(A~D) 题解
    CodeforcesRound919(Div.2)(A~D)题解A.SatisfyingConstraints题意:给你一些条件让你求出满足条件的整数有多少个。模拟即可。#include<bits/stdc++.h>usingnamespacestd;typedeflonglongll;constllMAXN=2e5+5;llTex=1,n;voidAC(){ cin>>n; lll=......
  • element-forge在Linux Centos中打包构建时遇到的异常问题解决方案
    环境:LinuxCentOS8x64electron:27.1.0electron-forge:7.1.0electrondev依赖包"devDependencies":{"@electron-forge/cli":"^7.1.0","@electron-forge/maker-deb":"^7.1.0","@electron-forge/maker-rpm&quo......