题目链接:B—合约数

题意:一棵树,有n个节点,从1编号到n。根节点的编号为p。给出每个节点的val[i]值,定义f(i)为以编号i为根节点的子树中(包括根节点),所有val[j]是合数并且是val[i]的约数的节点个数。求所有f(i)的和。答案对1e9+7取模。

题解:学长说可以用set的启发式合并或者splay的启发式合并。emmm,我太菜了不会这些怎么写。我的做法是:预处理范围内的数字是否是合数,然后对1-10000的数字用vector数组存下各自的因数。然后用dfs序,将各子树变成一个区间问题,用莫队算法解决。n是20000,每个数字不超过10000,这样复杂度就是 20000*(200+约数的个数,没几十个)。

ac代码:

#include<iostream>
#include<stdio.h>
#include<string>
#include<string.h>
#include<algorithm>
#include<vector>
#include<stack>
#include<queue>
#include<set>
#include<map>
#include<math.h>
using namespace std;
int val[20000+10];
int block;
int caz=0;
long long mod =1000000007;
int vis[20000+10];
int cishu[20000+10];
int num[20000+10];
int notprime[20000+10];
int prime[20000+10];
vector<int> vt[10000+10];
int cnt=0;
struct Query
{int l,r,pos;
}query[20000+10];
bool cmp(Query a,Query b)
{if(a.l/block!=b.l/block){return a.l<b.l;}return a.r<b.r;
}
struct Node
{int v,nne;
}node[40000+10];
int head[20000+10];
void build(int u,int v)
{node[cnt].v=v;node[cnt].nne=head[u];head[u]=cnt++;
}
void dfs(int rt)
{vis[rt]=caz;num[++cnt]=val[rt];query[rt].l=cnt;query[rt].pos=rt;for(int i=head[rt];i;i=node[i].nne){if(vis[node[i].v]<caz){dfs(node[i].v);}}query[rt].r=cnt;
}
int main()
{int t,n,p;//primefor(int i=2;i<=20000;i++){if(notprime[i]==0){prime[cnt++]=i;}for(int j=0;j<cnt&&prime[j]*i<=20000;j++){notprime[i*prime[j]]=1;if(i%prime[j]==0) break;}}//for(int i=1;i<=10000;i++){if(notprime[i]){double sq=sqrt(i);for(int j=1;j<=sq;j++){if(i%j==0){if(notprime[j])vt[i].push_back(j);if(notprime[i/j]&&i/j!=j)vt[i].push_back(i/j);}}}}//scanf("%d",&t);while(t--){long long ans=0,temp=0;scanf("%d%d",&n,&p);block=(int)sqrt(n);memset(cishu,0,sizeof(cishu));memset(head,0,sizeof(head));caz++;cnt=1;int a,b;for(int i=1;i<n;i++){scanf("%d%d",&a,&b);build(a,b);build(b,a);}for(int i=1;i<=n;i++){scanf("%d",&val[i]);}cnt=0;dfs(p);sort(query+1,query+1+n,cmp);int L=query[1].l,R=query[1].r;for(int i=L;i<=R;i++){cishu[num[i]]++;}temp=0;vector<int>::iterator it=vt[val[query[1].pos]].begin();for(;it!=vt[val[query[1].pos]].end();++it){temp+=cishu[*it];}ans=(ans+temp*query[1].pos%mod)%mod;printf("%lld\n",ans);for(int i=2;i<=n;i++){if(query[i].l>L){while(query[i].l>L){cishu[num[L]]--;L++;}}else if(query[i].l<L){while(query[i].l<L){L--;cishu[num[L]]++;}}if(query[i].r>R){while(query[i].r>R){R++;cishu[num[R]]++;}}else if(query[i].r<R){while(query[i].r<R){cishu[num[R]]--;R--;}}temp=0;for(it=vt[val[query[i].pos]].begin();it!=vt[val[query[i].pos]].end();it++){temp+=cishu[*it];}ans=(ans+temp*query[i].pos%mod)%mod;printf("%lld %lld\n",temp,ans);}printf("%lld\n",ans);}}

【牛客网】【埃森哲杯第十六届上海大学程序设计联赛春季赛暨上海高校金马五校赛】B—合约数【莫队做法】相关推荐

  1. 埃森哲杯第十六届上海大学程序设计联赛春季赛暨上海高校金马五校赛 B 合约数 (dfs+预处理)(dsu on tree)

    链接:https://ac.nowcoder.com/acm/contest/9115/B 题意:给定一棵n个节点的树,并且根节点的编号为p,第i个节点有属性值vali, 定义F(i): 在以i为根的 ...

  2. 埃森哲杯第十六届上海大学程序设计联赛春季赛暨上海高校金马五校赛 L-K序列

    埃森哲杯第十六届上海大学程序设计联赛春季赛暨上海高校金马五校赛 L-K序列 链接:https://www.nowcoder.com/acm/contest/91/L 来源:牛客网 题目描述 给一个数组 ...

  3. 埃森哲杯第十六届上海大学程序设计联赛春季赛暨上海高校金马五校赛 A-Wasserstein Distance

    埃森哲杯第十六届上海大学程序设计联赛春季赛暨上海高校金马五校赛 A-Wasserstein Distance 链接:https://www.nowcoder.com/acm/contest/91/A ...

  4. 埃森哲杯第十六届上海大学程序设计联赛春季赛暨上海高校金马五校赛 E-小Y吃苹果

    埃森哲杯第十六届上海大学程序设计联赛春季赛暨上海高校金马五校赛 E-小Y吃苹果 链接:https://www.nowcoder.com/acm/contest/91/E 来源:牛客网 题目描述 小Y买 ...

  5. 好久没撸c,第一场回状态的题(埃森哲杯第十六届上海大学程序设计联赛春季赛暨上海高校金马五校赛

    题目链接: 埃森哲杯第十六届上海大学程序设计联赛春季赛暨上海高校金马五校赛 A:Wasserstein Distance ## 题意:有2大堆柱状图的土(总体积相同,问从第一堆土移动到第二堆消耗最少的 ...

  6. 埃森哲杯第十六届上海大学程序设计联赛春季赛暨上海高校金马五校赛 I 二数(模拟)

    题目描述  我们把十进制下每一位都是偶数的数字叫做"二数". 小埃表示自己很聪明,最近他不仅能够从小数到大:2,3,4,5....,也学会了从大数到小:100,99,98...,他 ...

  7. 埃森哲杯第十六届上海大学程序设计联赛春季赛暨上海高校金马五校赛B合约数

    链接:https://www.nowcoder.com/acm/contest/91/B 来源:牛客网 题目描述 在埃森哲,员工培训是最看重的内容,最近一年,我们投入了 9.41 亿美元用于员工培训和 ...

  8. 埃森哲杯第十六届上海大学程序设计联赛春季赛暨上海高校金马五校赛 C序列变换...

    链接:https://www.nowcoder.com/acm/contest/91/C 来源:牛客网 没有账号的同学这样注册,支持博主 题目描述 给定两个长度为n的序列,ai, bi(1<=i ...

  9. 埃森哲杯第十六届上海大学程序设计联赛春季赛暨上海高校金马五校赛 A

    链接:https://www.nowcoder.com/acm/contest/91/A 来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 131072K,其他语言2621 ...

  10. 埃森哲杯第十六届上海大学程序设计联赛春季赛暨上海高校金马五校赛L

    K序列 链接:https://www.nowcoder.com/acm/contest/91/L 来源:牛客网 题目描述 给一个数组 a,长度为 n,若某个子序列中的和为 K 的倍数,那么这个序列被称 ...

最新文章

  1. Windows 编程[3] - 学习窗体生成的过程三
  2. nagios配置安装
  3. Jenkins设置用户权限
  4. SDNU 1423.入学考试(01背包)
  5. gateway网关配置入门
  6. Django 下添加左侧字段显示和搜索
  7. matlab迭代次数,怎么知道程序中的迭代次数呢
  8. php 获取相反值,php – 以相反的顺序从单向数组中获取数据
  9. 函数式编程 -- 函数组合
  10. systemtap gui
  11. Hello IDEA
  12. 磁盘类型 GetDriveType
  13. 【优化算法】符号LMS算法【含Matlab源码 697期】
  14. DIY智能战车制作教程,开启你的造车之旅
  15. 一键查询快递物流单号,分析提前签收
  16. VLAN与Trunk的配置
  17. 思维导图 XMind 闯关之路(第02关)插入各类符号
  18. 手撸springmvc乞丐版
  19. 大家小心了,做寄生虫排名骗子
  20. 亚马逊封号,新规则来了,你知道了吗?

热门文章

  1. 愚人节,60条短信祝你笑口常开……
  2. 全民一起玩Python基础篇第六课:复杂结构初步(列表、对象、模块等)(下)
  3. 微吼2022企业直播创见大会:探寻直播行业星辰大海
  4. 【摸鱼系列】如何用Python做一个有趣的Loading彩蛋游戏~
  5. Virtualbox源码分析20 NEM(Hyper-V兼容)1 Hyper-V架构和API介绍
  6. php搭建后台 xampp_运行PHP后台项目:xampp下载,安装,配置,运行PHP的web项目
  7. Nginx优化(精品)
  8. python翻译程序-Python:谷歌翻译20次的程序如何实现?
  9. springboot采用协同过滤算法的视频推荐系统的设计与实现毕业设计源码261620
  10. 慕课网Flask高级编程实战-7.静态文件、模板、消息闪现与Jinja2