CF1025D Recovering BST

题意:给定序列,问能否将其构成一颗BST,使得所有gcd(x, fa[x]) > 1

解:看起来是区间DP但是普通的f[l][r]表示不了根,f[l][r][root]又是n4的会超时,怎么办?

看了题解发现惊为天人......

f_l[l][r]表示[l, r]能否构成l-1的右子树,f_r[l][r]表示[l, r]能否构成r+1的左子树。

然后我们就发现这个神奇的东西变成n3了......

 1 #include <cstdio>
 2
 3 const int N = 710;
 4
 5 int gcd(int ta, int tb) {
 6     if(!tb) {
 7         return ta;
 8     }
 9     return gcd(tb, ta % tb);
10 }
11
12 inline void read(int &x) {
13     x = 0;
14     char c = getchar();
15     while(c < ‘0‘ || c > ‘9‘) {
16         c = getchar();
17     }
18     while(c >= ‘0‘ && c <= ‘9‘) {
19         x = (x << 3) + (x << 1) + c - 48;
20         c = getchar();
21     }
22     return;
23 }
24
25 int a[N];
26 bool G[N][N], val[N][N], var[N][N];
27
28 int main() {
29     int n;
30     read(n);
31     for(int i = 1; i <= n; i++) {
32         read(a[i]);
33     }
34
35     for(int i = 1; i <= n; i++) {
36         for(int j = i; j <= n; j++) {
37             G[i][j] = G[j][i] = (gcd(a[i], a[j]) > 1);
38         }
39     }
40     for(int i = 1; i <= n; i++) {
41         if(i > 1) {
42             val[i][i] = G[i][i - 1];
43         }
44         if(i < n) {
45             var[i][i] = G[i][i + 1];
46         }
47     }
48
49     for(int len = 2; len < n; len++) {
50         for(int l = 1; l + len - 1 <= n; l++) {
51             int r = l + len - 1;
52             for(int k = l; k <= r; k++) { // root
53                 bool t = (k == l ? 1 : var[l][k - 1]) & (k == r ? 1 : val[k + 1][r]);
54                 if(!t) {
55                     continue;
56                 }
57                 if(G[k][r + 1]) {
58                     var[l][r] = 1;
59                 }
60                 if(G[k][l - 1]) {
61                     val[l][r] = 1;
62                 }
63             }
64         }
65     }
66
67     for(int i = 1; i <= n; i++) {
68         bool t = (i == 1 ? 1 : var[1][i - 1]) & (i == n ? 1 : val[i + 1][n]);
69         if(t) {
70             printf("Yes");
71             return 0;
72         }
73     }
74     printf("No");
75     return 0;
76 }

AC代码

原文地址:https://www.cnblogs.com/huyufeifei/p/10351101.html

时间: 2024-10-31 04:15:08

CF1025D Recovering BST的相关文章

codeforce #505D - Recovering BST 区间DP

1025D 题意: 有一个递增序列,问能不能构建出一颗每条边的端点值都不互质的二叉排序树. 思路: 区间DP,但是和常见的区间DP不一样, 这里dp[i][j]表示的是区间[i,j]能否以i为根建立一个小二叉排序树. 所以可以得到dp[i][j] 为true, 要求在[i+1,j]中有一个k,dp[k][i+1]和dp[k][j]都为true. 或者在i点的左边取件中,即要求在[j][i-1]中有一个k,dp[k][j]和dp[k][i-1]都为true. #include <algorithm

Codeforces #505(div1+div2) D Recovering BST

题意:给你一个升序的数组,元素之间如果gcd不为1可以建边,让你判断是否可以建成一颗二叉搜索树. 解法:dp,首先建图,然后进行状态转移.因为如果点k左端与i相连,右端与k相连,则i和k可以相连,同时像左右两端拓展. 最后判断1和n是否相连即可. #include<cstdio> #include<algorithm> #include<cstring> #include<cmath> #include<vector> using namespa

Codefores 1025D Recovering BST

给定一个序列,问这个序列是否能够构成一个二叉搜索树,使得任一边连接的点的gcd大于1 区间dp #include <cstdio> #include <cstring> #include <algorithm> using namespace std; typedef long long LL; const int maxn = 710; int A[maxn]; bool G[maxn][maxn]; bool dp[maxn][maxn][2]; int gcd(i

Codeforces Round #505 (Div 1 + Div 2 Combined) Partial Solution

从这里开始 题目列表 瞎扯 Problem A Doggo Recoloring Problem B Weakened Common Divisor Problem C Plasticine zebra Problem D Recovering BST Problem E Colored Cubes Problem F Disjoint Triangles Problem G Company Acquisitions 瞎扯 打比赛,发现自己特别菜. 居然还苟且水上紫名 这个号不敢玩了.要努力学习

538. Convert BST to Greater Tree 二叉搜索树转换为更大树

Given a Binary Search Tree (BST), convert it to a Greater Tree such that every key of the original BST is changed to the original key plus sum of all keys greater than the original key in BST. Example: Input: The root of a Binary Search Tree like thi

验证给定序列是否是BST的preoder序列

from leetcode https://leetcode.com/problems/verify-preorder-sequence-in-binary-search-tree/ 比如序列 2, 1, 3 是如下图的BST的preorder 序列: 但是2, 3, 1就不会是一个preorder序列: 先复习一下BST,给定一个节点,其左子树的所有节点都小于该节点,右子树的所有节点都大于该节点:preorder序列是指在遍历该BST的时候,先记录根节点,再遍历左子树,然后遍历右子树:所以一个

笔试算法题(09):查找指定和值的两个数 &amp; 构造BST镜像树

出题:输入一个已经升序排序的数组和一个数字:要求在数组中查找两个数,这两个数的和正好等于输入的那个数字,输出任意一对数字就可以,要求时间复杂度是O(n): 分析:对于升序排序的数组{-i-j-k-m--},只有可能是i+m=j+k(j和k可能是同一个数),所以可以从两边往中间收缩而忽视其他交叉相加的情况: 解题: 1 void FindSumFactor(int *array, int length, int sum) { 2 int left=0, right=length-1; 3 whil

二叉查找树BST 模板

二叉查找树BST 就是二叉搜索树 二叉排序树. 就是满足 左儿子<父节点<右儿子 的一颗树,插入和查询复杂度最好情况都是logN的,写起来很简单. 根据BST的性质可以很好的解决这些东西 1.查询值 int Search(int k,int x) { if(x<a[k].key && a[k].l) Search(a[k].l,x); else if(x>a[k].key && a[k].r) Search(a[k].r,x); else retur

[LeetCode] Largest BST Subtree 最大的二分搜索子树

Given a binary tree, find the largest subtree which is a Binary Search Tree (BST), where largest means subtree with largest number of nodes in it. Note:A subtree must include all of its descendants.Here's an example: 10 / 5 15 / \ \ 1 8 7 The Largest