首页 > 其他分享 >U329011 trie pi 题解

U329011 trie pi 题解

时间:2024-02-27 10:23:29浏览次数:32  
标签:U329011 trie 题解 long 1e7 权值 pi 节点

花了2d打磨出来的题目,觉得很有意思。

先讲点无关的,这道题有两版,但都是对要求的量进行改动。

1.第一次要求的是y属性为a与y属性为b的两个节点的路径权值之和,对于要求的这个量,我们设v[i]为i到根节点的权值之和。那么我们先对a,b进行质因数分解,设dcg为a,b分解质因数后最长公共前缀的乘积,那么答案就是v[a]+v[b]-2*v[dcg]。

但可能会有人问wuhupai为什么不用这版,那是因为我发现了一个很有意思的性质:
y属性为a的这个点到根节点的路径权值和是a的最大质因子-1。解释起来也很简单:路上的权值全部都消掉了(觉得不理解可以手模一下),于是我想用这个性质搞点事情。于是与空气斗智斗勇3h,连续想出了5个时间复杂度能过的暴力,然后我发现要卡掉log n 的暴力要达到2^1e9也就是约3e8位的数,这肯定是不行的,于是今天早上灵光一闪,想出了这个题。

这道题的突破口就是y属性为a的这个点到根节点的路径权值和是a的最大质因子-1这个性质。我们只要能知道a的最大质因子就可以了,但是分解质因数的复杂度是O(n)的,1e7*1e7显然不能让我们通过此题,于是我们可以通过构造trie pi树的方式来用le7的时间预处理出1-1e7内所有数的最大质因子,然后边读入边取max就行了

#include<bits/stdc++.h>
using namespace std;
bool vis[10000005];
long long n,x,maxx=-1,len=0,num[5000000],v[10000005];
inline long long read(){
    char c=getchar();
    long long x=0,f=1;
    while(c<48){if(c=='-')f=-1;c=getchar();}
    while(c>47)x=(x*10)+(c^48),c=getchar();
    return x*f;
}
void solve(){
	for(long long i=2;i<=10000000;i++){
		if(vis[i]==false){
			len++;
			num[len]=i;
		}
		for(long long j=1;j<=len&&i*num[j]<=10000000;j++){
			vis[i*num[j]]=true;
			if(i%num[j]==0) break;
		}
	}
}
void dfs(long long from,long long sum){
	v[sum]=num[from];
	for(long long i=from;i<=len&&sum*num[i]<=10000000;i++){
		dfs(i,sum*num[i]);
	}
}
int main(){
	solve();
	dfs(1,1);
	v[1]=1;
	n=read();
	for(long long i=1;i<=n;i++){
		x=read();
		maxx=max(maxx,v[x]);
	}
	cout<<maxx-1;
	
	return 0;
}

标签:U329011,trie,题解,long,1e7,权值,pi,节点
From: https://www.cnblogs.com/wuhupai/p/18036311

相关文章

  • 时间戳时区问题解决方法
    在大家开发时会遇到这种情况:服务器是以东八时区为准(即中国标准时间),但是客户端会在不同地方,比如说雅典开罗(+2),格陵兰(-3),夏威夷(-10),当客户端选择某一个时间后,传递给服务器的时间戳,是以当地时区来解析的时间戳,这样就会出现一个时间差的问题,从而造成时间不准确。下面我们就来解决这种问......
  • [ABC314Ex] Disk and Segments题解(退火实现)
    一到比较水的退火题(虽然也调了3h)题意在平面直角坐标系中,有\(n\)条线段,第\(i\)条的端点是\((a_i,b_i)\)和$(c_i,d_i)$,任意线段不共点。(这里笔者为了方便会默认\(a_i<c_i\))你要在平面上画一个圆,使得任意一条线段都和圆周或圆内部有至少一个公共点,求满足条件的圆的最小......
  • P4666 [BalticOI 2011 Day1] Growing Trees题解(平衡树思想)
    自己第一道不看题解写出来的紫题,庆祝一下(没初始化种子导致调了30min)这是一个fhq-treap的题解思路来源:首先看题目,因为是序列上的问题,不难想到是一道数据结构题。首先看到操作C:对于这种操作,我们可以用平衡树解决,具体方法是,将树split成\(<min,min\lex\lemax,>max\)这......
  • AGC005D 题解
    传送门如果一个排列\(P\)满足对于所有的\(i\)都有\(|P_i-i|\neqk\),则称排列\(P\)为合法的。现给出\(n\)和\(k\),求有多少种合法的排列。由于答案很大,请输出答案对\(924844033\)取模的结果。\(2\leqn\leq2\times10^3\),\(1\leqk\leqn-1\)。一个新的trick:考虑......
  • 2024.2.25模拟赛T3题解
    题目推出dp柿子之后,枚举\(i\)的时候用线段树维护\(1-i\)的\(mex\)段,对于每一段,分别使用线段树套李超树维护,对于每个\(mex\)再次使用线段树套李超树维护即可code#include<bits/stdc++.h>usingnamespacestd;#defineN600005#defineintlonglongintn,m;consti......
  • 2024.2.25模拟赛T1题解
    题目考虑DP式子之后,可以通过堆维护函数,求出对应值code#include<bits/stdc++.h>usingnamespacestd;#defineintlonglong#defineN200005intzu,n,d,tg,num;inta[N];priority_queue<int>q;signedmain(){ scanf("%lld",&zu); while(zu--){ scanf(&qu......
  • 2024.2.25模拟赛T2题解
    题目枚举根之后,考虑每次连边的贡献,通过贡献算出每个点的权值,每次找出权值最大的点,又要保证父亲在儿子之前,所以将父亲和儿子合并,权值也合并一下即可code#include<bits/stdc++.h>usingnamespacestd;#defineN2005intans,n,k;intsz[N],deg[N],du[N],fu[N],f[N],h[N];str......
  • 2024.2.26模拟赛T2题解
    题目对询问扫描线,建出\(PAM\)的失配树之后,每次查询相当于,把\(r\)对应节点到根路径染色之后,有多少个节点的值大于\(l\),可以树剖+ODT实现code#pragmaGCCoptimize("Ofast","inline","-ffast-math")#pragmaGCCtarget("avx,sse2,sse3,sse4,mmx")#include<bits/s......
  • 2024.2.26模拟赛T1题解
    题目先建出圆方树,题目转换为数长度为\(2*L-1\)的路径数,长链剖分code#include<bits/stdc++.h>usingnamespacestd;#defineN2000005#definelllonglongintn,m,top,tot,cnt,L,k;intdfn[N],low[N],zhan[N],h[N];structAB{ inta,b,n;}d[N*4];voidcun(intx,int......
  • P7154 Sleeping Cows 题解
    传送门题意:给定两个数组\(a_i,b_i\),若\(a_i\leb_j\),则他俩可配对。求极大匹配的方案数。(极大不是最大,最大一定是极大)先考虑最大匹配方案数怎么求。把\(a\)和\(b\)从小到大排序。则每个\(a_i\)能匹配的\(b\)都是一段后缀,且随着\(i\)增大,这个后缀越来越小。于是从......