NOIp 2014 联合权值 By cellur925
题目传送门
这题自己(真正)思考了很久(欣慰)。
(轻而易举)地发现这是一棵树后,打算从Dfs序中下功夫,推敲了很久规律,没看出来(太弱了)。
开始手动枚举距离为2的情况,模模糊糊有了一些概念,但没有总结。(敲黑板:题目中发现规律与重要性质注意总结!)
其实,距离为2的情况只有两种:祖父/兄弟。
一个小时后放弃治疗。开始想暴力,很好想,我们对于每个点,枚举他的出边,再在每个出边中的出边中进行枚举,储存距离为2 的点。期望得分60pts.
大力交了一下:40pts,AC*6,WA*2,MLE*4.
MLE还有情可缘,vector开动态数组可能炸了,WA的那两个喵喵喵?
1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 #include<vector> 5 6 using namespace std; 7 typedef long long ll; 8 9 int n,tot; 10 ll sum,ans,p=10007; 11 int head[200090]; 12 ll val[200090]; 13 bool vis[200090]; 14 struct node{ 15 int to,next; 16 }edge[400090]; 17 vector<int>law[200090]; 18 19 void add(int x,int y) 20 { 21 edge[++tot].to=y; 22 edge[tot].next=head[x]; 23 head[x]=tot; 24 } 25 26 27 void dfs(int u) 28 { 29 for(int i=head[u];i;i=edge[i].next) 30 { 31 int v=edge[i].to; 32 for(int j=head[v];j;j=edge[j].next) 33 { 34 int g=edge[j].to; 35 if(g==u) continue; 36 law[u].push_back(g); 37 } 38 } 39 } 40 41 int main() 42 { 43 scanf("%d",&n); 44 for(int i=1;i<=n-1;i++) 45 { 46 int x=0,y=0; 47 scanf("%d%d",&x,&y); 48 add(x,y); 49 add(y,x); 50 } 51 for(int i=1;i<=n;i++) scanf("%d",&val[i]); 52 // dfs_pre(1); 53 // memset(vis,0,sizeof(vis)); 54 // dfs(1,0); 55 for(int i=1;i<=n;i++) 56 dfs(i); 57 for(int i=1;i<=n;i++) 58 { 59 for(int j=0;j<law[i].size();j++) 60 { 61 int u=i,v=law[i][j]; 62 ll tmp=val[u]%p*val[v]%p; 63 (sum+=tmp)%=p; 64 (ans=max(ans,tmp))%=p; 65 } 66 } 67 printf("%lld %lld",ans,sum); 68 return 0; 69 }
View Code
后来经过冷静分析看题解发现并不需要存儿子,当时每次更新一下就行了。而且最大值并不需要取膜。
再交一下60pts。TLE4个点,正常。
1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 #include<vector> 5 6 using namespace std; 7 typedef long long ll; 8 9 int n,tot; 10 ll sum,ans,p=10007; 11 int head[200090]; 12 ll val[200090]; 13 struct node{ 14 int to,next; 15 }edge[400090]; 16 17 void add(int x,int y) 18 { 19 edge[++tot].to=y; 20 edge[tot].next=head[x]; 21 head[x]=tot; 22 } 23 24 25 void dfs(int u) 26 { 27 for(int i=head[u];i;i=edge[i].next) 28 { 29 int v=edge[i].to; 30 for(int j=head[v];j;j=edge[j].next) 31 { 32 int g=edge[j].to; 33 if(g==u) continue; 34 ans=max(ans,val[u]*val[g]); 35 (sum+=val[u]*val[g])%=p; 36 } 37 } 38 } 39 40 int main() 41 { 42 scanf("%d",&n); 43 for(int i=1;i<=n-1;i++) 44 { 45 int x=0,y=0; 46 scanf("%d%d",&x,&y); 47 add(x,y); 48 add(y,x); 49 } 50 for(int i=1;i<=n;i++) scanf("%d",&val[i]); 51 // dfs_pre(1); 52 // memset(vis,0,sizeof(vis)); 53 // dfs(1,0); 54 for(int i=1;i<=n;i++) 55 dfs(i); 56 printf("%lld %lld",ans,sum); 57 return 0; 58 }
View Code
正解:我们只需要枚举每个点与他相连的每一条边即可,统计出与每个点相邻的最大点值与次大点值,全局最值用(最大点值*次大点值)更新,全局和用“乘法分配律“”维护。
1 #include<cstdio> 2 #include<algorithm> 3 4 using namespace std; 5 typedef long long ll; 6 7 int n,tot; 8 ll p=10007,sum,ans; 9 int head[200090],val[200090]; 10 struct node{ 11 int to,next; 12 }edge[400090]; 13 14 void add(int x,int y) 15 { 16 edge[++tot].to=y; 17 edge[tot].next=head[x]; 18 head[x]=tot; 19 } 20 21 ll llmax(ll a,ll b) 22 { 23 if(a>=b) return a; 24 else return b; 25 } 26 27 void update(int x) 28 { 29 int maxx=0,maxs=0; 30 ll cnt=0; 31 for(int i=head[x];i;i=edge[i].next) 32 { 33 int y=edge[i].to; 34 if(val[y]>maxx) maxs=maxx,maxx=val[y]; 35 else if(val[y]>maxs) maxs=val[y]; 36 (sum+=cnt*val[y])%=p; 37 (cnt+=val[y])%=p; 38 } 39 ans=llmax(ans,maxs*maxx); 40 } 41 42 int main() 43 { 44 scanf("%d",&n); 45 for(int i=1;i<=n-1;i++) 46 { 47 int x=0,y=0; 48 scanf("%d%d",&x,&y); 49 add(x,y);add(y,x); 50 } 51 for(int i=1;i<=n;i++) scanf("%d",&val[i]); 52 for(int i=1;i<=n;i++) update(i); 53 printf("%lld %lld",ans,2*sum%p); 54 return 0; 55 }
View Code
转载于:https://www.cnblogs.com/nopartyfoucaodong/p/9505149.html
NOIp 2014 联合权值 By cellur925相关推荐
- NOIP 2014 联合权值
题目链接: https://www.luogu.org/problemnew/show/P1351 参考洛谷题解: 使用链式前向星储存图.如果使用深度优先搜索的话,是会超时的,如果遍历中间的点,虽然比 ...
- NOIP 2014TG 联合权值
原题地址 https://www.luogu.org/problemnew/show/P1351 主要思路:推公式 由上图得到(元素的和的平方)等于(元素的平方和)加(两倍各元素两两相乘) 然后枚举中 ...
- NOIp 2014 #2 联合权值 Label:图论 !!!未AC
题目描述 无向连通图G 有n 个点,n - 1 条边.点从1 到n 依次编号,编号为 i 的点的权值为W i ,每条边的长度均为1 .图上两点( u , v ) 的距离定义为u 点到v 点的最短距离. ...
- 联合权值 NOIP2014 提高组 Day1 T2
codevs 3728 联合权值 题目描述 无向连通图G 有n 个点,n - 1 条边.点从1 到n 依次编号,编号为 i 的点的权值为W i ,每条边的长度均为1 .图上两点( u , v ) 的距 ...
- [NOIP2014]联合权值
NOIp2014提高组 [题目描述] 无向连通图G 有n 个点,n - 1 条边.点从1 到n 依次编号,编号为 i 的点的权值为W i ,每条边的长度均为1 .图上两点( u , v ) 的距 ...
- [Luogu 1351] NOIP2014 联合权值
[Luogu 1351] NOIP2014 联合权值 存图,对于每一个点 \(u\),遍历它的所有邻接点.以 \(u\) 为中转点的点对中,\((x,y)\) 的联合权值 \(w_x \cdot w_ ...
- 【学术篇】luogu1351[NOIP2014 提高组]联合权值
一道提高组的题..... 传送门:题目在这里.... 现在都懒得更自己的blog了,怕是太颓废了_ (:з」∠) _ 好久没做题了,手都生了.(好吧其实是做题方面手太生了) 这题我都不想讲了,把代码一 ...
- P1351 联合权值[鬼畜解法]
题目描述 无向连通图 G 有 n 个点,n−1 条边.点从 1 到 n 依次编号,编号为 i 的点的权值为 Wi,每条边的长度均为 1.图上两点 (u,v) 的距离定义为 u 点到 v 点的最短距离 ...
- 洛谷 1351 联合权值
[题解] 每个点维护各个儿子的前后缀最大值.权值和,这样就可以统计儿子之间相乘的答案.然后每个节点再乘它的祖父的权值去更新答案即可. 1 #include<cstdio> 2 #inclu ...
最新文章
- 【转载】Git 常用命令大全
- nginx反向代理原理及配置详解
- 全球及中国增强现实产业战略布局及运营前景决策分析报告2021-2027年
- list-style-type:decimal在IE中显示全是1的解析
- 循序渐进学Python2变量与输入
- Android(java)学习笔记63:Clock App 编写报错01
- 一种User Mode下访问物理内存及Kernel Space的简单实现
- 课后作业-阅读任务-阅读笔记-2
- 使用头文件的原因和规范
- 使用某些 DOCTYPE 时会导致 document.body.scrollTop 失效
- 主子表对应的字段_Power Pivot针对表筛选的函数及差异
- C++中嵌入python程序——命令行模式
- linux 执行 ktr脚本,kettle在linux下面用于shell脚本执行:转换或者作业
- 南京大学计算机学院英才计划,南京大学以“英才计划”为切入点 向前衔接高中...
- Kotlin初级(2)- - - 空安全.md
- Calling brew cask install is disabled! Use brew install [--cask] instead
- 【shaderforge学习笔记】 Vector Operations(向量运算)
- 14、W601之AHT10温湿度传感器
- 笔记本 ASUS A3E 改用Windows Server 2003 的几个问题
- 关于使用Artery插件的一些积累1
热门文章
- python模拟购物车流程_用函数模拟简单的购物车(Python)
- 计算机考研 东华大学,东华大学(专业学位)计算机技术考研难吗
- 组件服务-计算机-我的电脑出现红色向下箭头的解决办法
- Mysql安装的目录结构详解
- 10蓝牙_小米10手机专用?小米“真无线蓝牙耳机Air 2s”评测
- 数据分析中常用的数据模型
- win10关机后cpu风扇还在转_win10电脑关机后cpu风扇还在转动_网站服务器运行维护...
- wpf 怎样判断是否选中 checkbox_怎样判断一个人是否缺爱?
- 防抖与节流方案_关于图片懒加载的几种方案
- excel函数手册_一个函数高手的成长之路