角色属性树
原题链接
题目大意:
\(对一颗树上的节点的最近有相同因数的上司\)
\(需要做到维护和修改两种操作\)
\(idea:直接做即可 因为给出的数据随机 虽然在最坏情况下会达到n*k但是根据数学期望 gcd(a,b)>1在经过一系列小学计算得出期望约为O(klogn)\)
\(注意:因为要迭代父亲 所以需要反向建树\)
\(code:\)
点击查看代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
#define pb push_back
#define pii pair<int,int>
#define all(x) x.begin(),x.end()
const int mod=1e9+7;
int qpw(int a,int b){int ans=1;while(b){if(b&1)ans=ans*a%mod;a=a*a%mod,b>>=1;}return ans;}
void solve() {
int n,k;cin>>n>>k;
vector G(n+1,vector<int>());
vector<int>val(n+1);
for(int i=1;i<=n;i++)cin>>val[i];
for(int i=1;i<n;i++){
int x,y;cin>>x>>y;
G[y].pb(x);
}
function<int(int,int)>dfs=[&](int x,int now){
for(auto &fa:G[x]){
if(gcd(val[fa],val[now])>1){
return fa;
}
return dfs(fa,now);
}
return -1ll;
};
while(k--){
int op;
cin>>op;
if(op==1){
int u;cin>>u;
int ans=dfs(u,u);
cout<<ans<<'\n';
}else {
int u,x;cin>>u>>x;
val[u]=x;
}
}
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
int _=1;
// cin>>_;
while(_--)solve();
}