题解:P13875 [蓝桥杯 2024 省研究生组] 植物生命力
P13875 [蓝桥杯 2024 省研究生组] 植物生命力 - 题解
思路:
看起来不太可做,但我们可以注意到题目中有这样一句话:对于所有的测试用例,
对于这道题,一个显然的思路就是:对于所有的
这么多次,即
一些显然的优化:可以用树状数组代替线段树,以减小常数;把权值插入树状数组的同时打标记,这样在枚举整数倍的时候可以做到
代码:
vector<int> mp[100005];
int w[100005];
bool vis[100005];
int n,rt;
long long ans;
int c[100005];
void add(int x,int v)
{
for(;x<=n;x+=lowbit(x)) c[x]+=v;
}
int qry(int x)
{
int res=0;
for(;x;x-=lowbit(x)) res+=c[x];
return res;
}
void dfs(int u,int f)
{
vis[w[u]]=1;
add(w[u],1);
for(int v:mp[u])
{
if(v==f) continue;
dfs(v,u);
}
for(int i=2;i*w[u]<=n;i++)
ans-=vis[i*w[u]];
ans+=qry(n)-qry(w[u]);
vis[w[u]]=0;
add(w[u],-1);
}
char QQ,coin;
decltype(QQ+coin) main()
{
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
cin>>n>>rt;
for(int i=1;i<=n;i++)
cin>>w[i];
for(int i=1;i<n;i++)
{
int u,v;
cin>>u>>v;
mp[u].push_back(v);
mp[v].push_back(u);
}
dfs(rt,0);
cout<<ans<<"\n";
return ~(-1);
}