• CodeForces


    ( ext{Description})

    传送门

    ( ext{Solution})

    暴力枚举是不可行的。(搜索大佬随手切题

    发现复杂度这么高是因为我们枚举了左边界,右边界,根节点,根节点的 (2) 个儿子。

    这个时候我们就要用到二叉搜索树的一个性质:根节点大于左子树,小于右子树。

    我们枚举一段区间并制定其为左子树或右子树,这样我们就能确定根。然后判断能否成立即可。

    最后枚举根就行了。

    ( ext{Code})

    #include<cstdio>
    
    const int N = 702;
    int n, a[N];
    bool arr[N][N], l[N][N], r[N][N];//l与r数组:i到j区间可否成为左/右子树
    
    int read() {
    	int x = 0, f = 1; char s;
    	while((s = getchar()) > '9' || s < '0') if(s == '-') f = -1;
    	while(s >= '0' && s <= '9') {
    		x = (x << 1) + (x << 3) + (s ^ 48);
    		s = getchar();
    	}
    	return x * f;
    }
    
    int gcd(const int a, const int b) {
    	if(! b) return a;
    	return gcd(b, a % b);
    }
    
    int main() {
    	int j;
    	n = read();
    	for(int i = 1; i <= n; ++ i) a[i] = read();
    	for(int i = 1; i <= n; ++ i)
    		for(int j = 1; j <= n; ++ j)
    			arr[i][j] = (gcd(a[i], a[j]) == 1 ? 0 : 1);
    	for(int i = 1; i <= n; ++ i) l[i][i] = r[i][i] = 1;
    	for(int dis = 1; dis < n; ++ dis)
    		for(int i = 1; i <= n - dis; ++ i) {
    			j = i + dis;
    			for(int k = i; k < j; ++ k) l[i][j] |= (arr[k][j] & l[i][k] & r[k][j - 1]);
    			for(int k = i + 1; k <= j; ++ k) r[i][j] |= (arr[i][k] & l[i + 1][k] & r[k][j]);
    		}
    	for(int i = 1; i <= n; ++ i)
    		if(l[1][i] & r[i][n]) {
    			puts("Yes");
    			return 0;
    		}
    	puts("No");
    	return 0;
    }
    
  • 相关阅读:
    python2和3切换时的几个注意点会报错
    Python异常UnicodeEncodeError 'gbk' codec can't encode character 'xa0'
    python爬虫使用Xpath爬取指定位置的内容
    问题账户需求分析
    2018年春季个人阅读计划
    我们应当怎样做需求分析
    人月神话读后感3
    人月神话读后感2
    线程池
    生产者消费者
  • 原文地址:https://www.cnblogs.com/AWhiteWall/p/14055372.html
Copyright © 2020-2023  润新知