//最近工作繁忙,决定先不通刷cf套题,换刷难度系数2000以上的题
题意:给一颗以1为根的树,有q次操作,1 v表示求根到v权值与av不互质的深度最大的点。2 u w 表示把节点 u 的权值改为w,最多50次修改。
思路:我应该是第一个用主席树切这个题的吧....把每个节点的权值质因数分解,每颗线段树 rt[i] 存从根到 i 节点,每个质因数 x 节点存深度最大的点(该点权值包含x质因数),然后每次查询v,分解v的质因数,然后找v的父节点的主席树找这些质因数包含最大深度的节点就行。
#include<bits/stdc++.h>
using namespace std;
const int N=2e6,maxm=1e5+10;
int vis[2000001],pri[200010],cnt,a[maxm],f[maxm],dep[maxm],id[maxm*20];
vector<int>G[100001];
int rt[maxm],ls[maxm*20*7],rs[maxm*20*7],tree[maxm*20*7],sz;
void init()
{
for(int i=2;i<=N;i++)
if(!vis[i])
{
pri[++cnt]=i;
id[i]=cnt;
for(int j=i;j<=N;j+=i)
vis[j]=1;
}
}
void up(int pre,int &o,int l,int r,int k,int v)
{
o=++sz;
ls[o]=ls[pre];
rs[o]=rs[pre];
if(l==r)
{
tree[o]=v;
return;
}
int m=(l+r)/2;
if(k<=m)up(ls[pre],ls[o],l,m,k,v);
else up(rs[pre],rs[o],m+1,r,k,v);
}
int qu(int o,int l,int r,int k)
{
if(l==r)
return tree[o];
int m=(l+r)/2;
if(k<=m)return qu(ls[o],l,m,k);
else return qu(rs[o],m+1,r,k);
}
void dfs(int u,int fa,int deep)
{
dep[u]=deep;
f[u]=fa;
int k=1;
int m=a[u];
for(;k<=cnt&&pri[k]*pri[k]<=m;k++)
if(m%pri[k]==0)
{
int x=pri[k];
if(!rt[u])
up(rt[fa],rt[u],1,200000,k,u);
else
up(rt[u],rt[u],1,200000,k,u);
while(m%x==0&&m>=x)
m/=x;
}
if(m!=1)
{
if(!rt[u])
up(rt[fa],rt[u],1,200000,id[m],u);
else
up(rt[u],rt[u],1,200000,id[m],u);
}
if(!rt[u])rt[u]=rt[fa];
for(int i=0;i<G[u].size();i++)
if(G[u][i]!=fa)
dfs(G[u][i],u,deep+1);
}
int main()
{
init();
int n,q,u,v,op;
scanf("%d%d",&n,&q);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
for(int i=1;i<n;i++)
{
scanf("%d%d",&u,&v);
G[u].push_back(v);
G[v].push_back(u);
}
dfs(1,0,1);
while(q--)
{
scanf("%d%d",&op,&u);
if(op==1)
{
int ans=-1;
v=f[u];
int m=a[u],k=1;
for(;k<=cnt&&pri[k]*pri[k]<=m;k++)
if(m%pri[k]==0)
{
int x=pri[k];
{
int tmp=qu(rt[v],1,200000,k);
if(ans==-1&&tmp)ans=tmp;
if(tmp&&dep[ans]<dep[tmp])
ans=tmp;
}
while(m%x==0&&m>=x)
m/=x;
}
if(m!=1)
{
int tmp=qu(rt[v],1,200000,id[m]);
if(ans==-1&&tmp)ans=tmp;
if(tmp&&dep[ans]<dep[tmp])
ans=tmp;
}
printf("%d\n",ans);
}
else
{
scanf("%d",&a[u]);
for(int i=1;i<=n;i++)
rt[i]=0;
for(int i=1;i<=sz;i++)
ls[i]=rs[i]=tree[i]=0;
sz=0;
dfs(1,0,1);
}
}
}