F - Factor-Free Tree Gym - 101623F(质数,中序遍历,区间)

2024-04-15 23:48

本文主要是介绍F - Factor-Free Tree Gym - 101623F(质数,中序遍历,区间),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在这里插入图片描述

题意:
给出一颗树的中序遍历,要求还原这棵树使得每一个节点的值和其祖先互质

思路:
参考claris博客题解。

对每个数质因子分解,算出每个数左边的第一个不互质位置,右边第一个不互质位置。
维护每个点对应的区间,也就是其对应子树。
将这些区间放在栈里面,如果当前区间包含栈顶区间,那么弹出栈顶。
则按照中序遍历左中右的顺序,最后一个弹出的区间为当前点的左子树,当前栈顶区间为节点父子节点。

则无解情况为栈顶区间不包含当前区间,此时父节点不能包括子节点。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
#include <queue>
using namespace std;const int INF = 0x3f3f3f3f;
const int maxn = 1e6 + 7;
const int MAXN = 1e7 + 7;
struct STK {int l,r;int id;
}stk[maxn];int n;
int fa[maxn];
int L[maxn],R[maxn],a[maxn];
int pre[MAXN],p[MAXN],v[MAXN],tot;void init() {for(int i = 2;i < MAXN;i++) {if(!v[i]) {p[++tot] = i;v[i] = i;}for(int j = 1;j <= tot && 1ll * i * p[j] < MAXN;j++) {v[i * p[j]] = p[j];if(i % p[j] == 0) break;}}
}void Pre() {for(int i = 1;i <= n;i++) {int x = a[i];while(x > 1) {L[i] = max(L[i],pre[v[x]]);x /= v[x];}L[i]++;x = a[i];while(x > 1) {pre[v[x]] = i;x /= v[x];}}for(int i = 2;i < MAXN;i++) pre[i] = n + 1;for(int i = n;i >= 1;i--) {R[i] = n + 1;int x = a[i];while(x > 1) {R[i] = min(R[i],pre[v[x]]);x /= v[x];}R[i]--;x = a[i];while(x > 1) {pre[v[x]] = i;x /= v[x];}}
}int main() {init();scanf("%d",&n);for(int i = 1;i <= n;i++) scanf("%d",&a[i]);Pre();int top = 0;stk[0].l = 0;stk[0].r = INF;for(int i = 1;i <= n;i++) {int left = i;stk[top + 1].id = 0;while(L[i] <= stk[top].l && stk[top].r <= R[i]) {left = min(left,stk[top].l);top--;}fa[stk[top + 1].id] = i;fa[i] = stk[top].id;stk[++top].l = left;stk[top].id = i;stk[top].r = min(R[i],stk[top - 1].r);if(stk[top - 1].r < i) {printf("impossible\n");return 0;}}for(int i = 1;i <= n;i++) {printf("%d ",fa[i]);}return 0;
}

这篇关于F - Factor-Free Tree Gym - 101623F(质数,中序遍历,区间)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/907260

相关文章

hdu 1754 I Hate It(线段树,单点更新,区间最值)

题意是求一个线段中的最大数。 线段树的模板题,试用了一下交大的模板。效率有点略低。 代码: #include <stdio.h>#include <string.h>#define TREE_SIZE (1 << (20))//const int TREE_SIZE = 200000 + 10;int max(int a, int b){return a > b ? a :

hdu4267区间统计

题意:给一些数,有两种操作,一种是在[a,b] 区间内,对(i - a)% k == 0 的加value,另一种操作是询问某个位置的值。 import java.io.BufferedInputStream;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import

hdu4417区间统计

给你一个数列{An},然后有m次查询,每次查询一段区间 [l,r] <= h 的值的个数。 import java.io.BufferedInputStream;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamRead

hdu3333区间统计

题目大意:求一个区间内不重复数字的和,例如1 1 1 3,区间[1,4]的和为4。 import java.io.BufferedInputStream;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;

leetcode105 从前序与中序遍历序列构造二叉树

根据一棵树的前序遍历与中序遍历构造二叉树。 注意: 你可以假设树中没有重复的元素。 例如,给出 前序遍历 preorder = [3,9,20,15,7]中序遍历 inorder = [9,3,15,20,7] 返回如下的二叉树: 3/ \9 20/ \15 7   class Solution {public TreeNode buildTree(int[] pr

树(Tree)——《啊哈!算法》

树 什么是树?树是一种特殊的图,不包含回路的连通无向树。 正因为树有着“不包含回路”这个特点,所以树就被赋予了很多特性。 一棵树中的任意两个结点有且仅有唯一的一条路径连通。一棵树如果有n个结点,那么它一定恰好有n-1条边。在一棵树中加一条边将会构成一个回路。 一棵树有且只有一个根结点。 没有父结点的结点称为根结点(祖先)。没有子结点的结点称为叶结点。如果一个结点既不是根结点也不是叶

PHP实现二叉树遍历(非递归方式,栈模拟实现)

二叉树定义是这样的:一棵非空的二叉树由根结点及左、右子树这三个基本部分组成,根据节点的访问位置不同有三种遍历方式: ① NLR:前序遍历(PreorderTraversal亦称(先序遍历)) ——访问结点的操作发生在遍历其左右子树之前。 ② LNR:中序遍历(InorderTraversal) ——访问结点的操作发生在遍历其左右子树之中(间)。 ③ LRN:后序遍历(PostorderT

react笔记 8-17 属性绑定 class绑定 引入图片 循环遍历

1、绑定属性 constructor(){super()this.state={name:"张三",title:'我是一个title'}}render() {return (<div><div>aaaaaaa{this.state.name}<div title={this.state.title}>我是一个title</div></div></div>)} 绑定属性直接使用花括号{}   注

226 Invert Binary Tree

//226 Invert Binary Tree//算法思路:主要使用递归算法public class Solution {public TreeNode invertTree(TreeNode root) {//1 出口 空节点if (root==null)return null;//2 递归 调用自己TreeNode left = root.left;TreeNode right = ro

hashmap的存值,各种遍历方法

package com.jefflee;import java.util.HashMap;import java.util.Iterator;import java.util.Map;public class HashmapTest {// 遍历Hashmap的四种方法public static void main(String[] args) {//hashmap可以存一个null,把