这个题被wa成傻逼了。。。。
ma[i][j]表示i,j能不能形成一条直接作为排序二叉树的边,n^3更新维护ma即可,按说应该是要爆复杂度的,数据玄学吧。。
#include<iostream> #include<cstdio> #include<cmath> #include<queue> #include<vector> #include<string.h> #include<cstring> #include<algorithm> #include<set> #include<map> #include<fstream> #include<cstdlib> #include<ctime> #include<list> #include<climits> #include<bitset> using namespace std; #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("ouput.txt", "r", stdin);freopen("output.txt", "w", stdout); #define left asfdasdasdfasdfsdfasfsdfasfdas1 #define tan asfdasdasdfasdfasfdfasfsdfasfdas typedef long long ll; typedef unsigned int un; const int desll[4][2]={{0,1},{0,-1},{1,0},{-1,0}}; const ll mod=1e9+7; const int maxn=7e2+7; const int maxm=1e6+7; const double eps=1e-4; int m,n; int ar[maxn]; char ch[maxn]; int gcd(int a,int b) { return b==0?a:gcd(b,a%b); } bool gcdl[maxn][maxn]; bool ma[maxn][maxn],vis[maxn]; set<int> ve[maxn]; void init(){ memset(gcdl,0,sizeof(gcdl)); for(int i=1;i<=n;i++){ for(int j=i;j<=n;j++){ if(gcd(ar[i],ar[j])>1)gcdl[i][j]=gcdl[j][i]=1; } } memset(ma,0,sizeof(ma)); } void dfs(int u) { vis[u]=1; for(int i=1;i<=n;i++){ if(i==u || ma[u][i]==0)continue; if(vis[i]==0)dfs(i); } } int main() { scanf("%d",&n); for(int i=1;i<=n;i++){ scanf("%d",&ar[i]); } init(); for(int i=1;i<=n;i++){ if(i>1){ if(gcdl[i][i-1])ma[i][i-1]=1; } if(i<n){ if(gcdl[i][i+1])ma[i][i+1]=1; } } for(int j=2;j<=n;j++){ for(int i=1;i<=n;i++){ if(i+j<=n && ma[i][i+j]==0){ if(gcdl[i][i+j] && ma[i+j][i+1]){ ma[i][i+j]=1; } if(ma[i][i+j]==0){ for(int k=i+1;k<i+j;k++){ if(ma[i][k] && ma[k][i+j]){ ma[i][i+j]=1; break; } } } } if(i-j>=1 && ma[i][i-j]==0){ if(gcdl[i][i-j] && ma[i-j][i-1]){ ma[i][i-j]=1; } if(ma[i][i-j]==0){ for(int k=i-1;k>i-j;k--){ if(ma[i][k] && ma[k][i-j]){ ma[i][i-j]=1; break; } } } } } } bool fond=false; for(int i=2;i<n;i++){ if(ma[i][1] && ma[i][n]){ fond=true;break; } } if(ma[1][n] || ma[n][1])fond=true; if(fond)printf("Yes "); else printf("No "); return 0; }