数学,结论题
告诉大家一个结论。
求解任意区间的gcd中,gcd的变化最多只有log2(max(num))次
为什么这样说呢?
现在假设我们求解从L到后面任意一个前缀的gcd
我们想想哈,这个gcd值一定是<=a[L]的
我们想想这个gcd的变化,每次变化最小还是得/2那么最多log2(a[L])次
实际上变化的还会更少!!!
那么依据这个理论,我们可以做出这题。
时空复杂度其实是很小的。
#include<iostream> #include<algorithm> #include<map> using namespace std; typedef long long ll; typedef pair<ll,ll> pll; const int max_n = 1e5+100; const ll mod = 1e9+7; struct edge{ int to,next; }E[max_n<<1]; int head[max_n]; int cnt=1; void add(int from,int to){ E[cnt].to=to; E[cnt].next=head[from]; head[from]=cnt++; } ll x[max_n]; int n; map<ll,ll> mp[max_n]; ll ans=0; void dfs(int u,int fa){ mp[u][x[u]]++; for (pll it:mp[fa])mp[u][__gcd(it.first,x[u])]+=it.second; for (int i=head[u];i;i=E[i].next) if (E[i].to!=fa)dfs(E[i].to,u); for (pll it:mp[u])ans = (ans+it.first*it.second)%mod; } int main(){ cin>>n; for (int i=1;i<=n;++i)cin>>x[i]; for (int i=1,u,v;i<n;++i){ cin>>u>>v; add(u,v);add(v,u); }dfs(1,0); cout<<ans<<endl; }