• 【JZOJ6368】质树(tree)


    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(nlog_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
    ");return 0;}
    	fo(i,1,n)printf("%lld ",fa[i]);
    	return 0;
    }
    
  • 相关阅读:
    const,var,let区别(转载)
    在windows上搭建redis集群
    Linux学习笔记—vim程序编辑器
    Linux学习笔记—文件与文件系统的压缩与打包(转载)
    Linux学习笔记—Linux磁盘与文件系统管理(转载)
    五,mysql优化——sql语句优化小技巧
    八,mysql优化——读写分离
    六,mysql优化——小知识点
    七,mysql优化——表的垂直划分和水平划分
    三,mysql优化--sql语句优化之索引一
  • 原文地址:https://www.cnblogs.com/horizonwd/p/11610005.html
Copyright © 2020-2023  润新知