• 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代码
  • 相关阅读:
    敌兵布阵(线段树单点更新+区间查询)
    小明上学(CCF认证2018-12-1 )
    There Are Two Types Of Burgers (Educational Codeforces Round 71)
    Bad Prices ( Codeforces Round #582 )
    Redis热点key优化
    Redis big key处理
    Redis的安全问题
    Redis的flushall/flushdb误操作
    Redis在linux系统中的优化
    Redis之缓存设计
  • 原文地址:https://www.cnblogs.com/huyufeifei/p/10351101.html
Copyright © 2020-2023  润新知