description

大神 wyp 手里有棵二叉树,每个点有一个点权。大神 wyp 的这棵树是质树,因为

随便找两个不同的点 u, v,只要 u 是 v 的祖先,都满足 u 和 v 的点权互质。

现在你通过偷看了解到了大神 wyp 这棵树的中序遍历的点权值,你想复原出大神

wyp 的树,或者指出不可能。

阅读样例以更好地理解本题。


analysis

  • 首先预处理质数,对于每个数,可以分解质因数

  • 然后用一个桶前后各扫一遍分别得出每个数往前往后区间内与其都互质的最远位置

  • 如果对于\([l,r]\)区间,枚举一个可行位置\(i\),拆分成\([l,i-1],[i+1,r]\),复杂度\(O(n^2)\)

  • 但是如果同时从头和尾往中间找,每个层搜索长度减半,复杂度\(O(n\log_2n)\)


code

#pragma GCC optimize("O3")
#pragma G++ optimize("O3")
#include<stdio.h>
#include<string.h>
#include<algorithm>
#define MAXN 1000005
#define MAX 10000005
#define ll long long
#define reg register ll
#define ha 1926081719491001
#define fo(i,a,b) for (reg i=a;i<=b;++i)
#define fd(i,a,b) for (reg i=a;i>=b;--i) using namespace std; bool bz[MAX];
ll left[MAXN],right[MAXN];
ll a[MAXN],p[MAX],bucket[MAX],fa[MAXN],mxp[MAX];
ll n,tot,flag=1; inline ll read()
{
ll x=0,f=1;char ch=getchar();
while (ch<'0' || '9'<ch){if (ch=='-')f=-1;ch=getchar();}
while ('0'<=ch && ch<='9')x=x*10+ch-'0',ch=getchar();
return x*f;
}
inline ll max(ll x,ll y){return x>y?x:y;}
inline ll min(ll x,ll y){return x<y?x:y;}
inline void init()
{
#define MAXX 10000000
memset(bz,1,sizeof(bz));
fo(i,2,MAXX)
{
if (bz[i])p[++tot]=i,mxp[i]=i;
for (reg j=1;j<=tot && i*p[j]<=MAXX;++j)
{bz[i*p[j]]=0,mxp[i*p[j]]=p[j];if (i%p[j]==0)break;}
}
}
inline bool judge(ll i,ll l,ll r)
{
if (left[i]<=l && right[i]>=r)return 1;
return 0;
}
inline void dfs(ll l,ll r,ll x)
{
if (l>r)return;
if (l==r){fa[l]=x;return;}
fo(len,0,(r-l)/2)
{
ll i=l+len,j=r-len;
if (judge(i,l,r))
{
fa[i]=x,dfs(l,i-1,i),dfs(i+1,r,i);
return;
}
if (judge(j,l,r))
{
fa[j]=x,dfs(l,j-1,j),dfs(j+1,r,j);
return;
}
}
flag=0;return;
}
int main()
{
//freopen("T3.in","r",stdin);
freopen("tree.in","r",stdin);
freopen("tree.out","w",stdout);
n=read(),init();fo(i,1,n)a[i]=read();
fo(i,1,n)
{
ll x=a[i];left[i]=1;
while (x>1)
{
ll tmp=mxp[x];
left[i]=max(left[i],bucket[tmp]?bucket[tmp]+1:1);
bucket[tmp]=i;
while (x%tmp==0)x/=tmp;
}
}
memset(bucket,0,sizeof(bucket));
fd(i,n,1)
{
ll x=a[i];right[i]=n;
while (x>1)
{
ll tmp=mxp[x];
right[i]=min(right[i],bucket[tmp]?bucket[tmp]-1:n);
bucket[tmp]=i;
while (x%tmp==0)x/=tmp;
}
}
tot=0,dfs(1,n,0);
if (!flag){printf("impossible\n");return 0;}
fo(i,1,n)printf("%lld ",fa[i]);
return 0;
}

最新文章

  1. software_testing_work2_question1(改)_edition
  2. navicat自动备份数据
  3. ASM ClassReader failed to parse class file - probably due to a new Java class file version that isn&#39;t supported yet
  4. 【转载】 JQuery.Gantt(甘特图) 开发指南
  5. python sorted和sort
  6. Webstrom快捷键大全
  7. JavaScript显示分页按钮
  8. Maven+Spring+MVC结构中,jetty/tomcat是如何启动项目的[转]
  9. python27读书笔记0.1
  10. FineUI表单验证
  11. UVALive 4031 Integer Transmission(贪心 + DP)
  12. servlet与Javabean之间的区别
  13. web面试题
  14. 字符编码(ASCII、ANSI、GB2312、UTF-8等)系统梳理
  15. poj 1696 极角排序求最长逆时针螺旋线
  16. 根Activity启动过程
  17. Vue中使用Cropper.js裁剪图片
  18. windows的tasklist使用
  19. vue系列之flex经典案例
  20. dongle0

热门文章

  1. Ubuntu18.04 一键升级Python所有第三方包
  2. assignment of day four
  3. 45-Ubuntu-用户管理-10-chmod修改文件|目录权限
  4. USACO2007 The Bale Tower /// DFS oj21160
  5. 将时间 &#39;2018-08-06T10:00:00.000Z&#39; 格式转化为本地时间
  6. 使用lombok时@Setter @Getter无效
  7. tomcat 端口被占用 项目端口号被占用怎么解决
  8. delphi RichView的使用介绍
  9. 使用VC6.0编译C++代码的时候报错:fatal error C1071: unexpected end of file found in comment(Mark ZZ)
  10. delphi透明panel组件或者制作方法