首页 > 其他分享 >题解:洛谷 P1351 [NOIP2014 提高组] 联合权值

题解:洛谷 P1351 [NOIP2014 提高组] 联合权值

时间:2025-01-21 19:03:18浏览次数:3  
标签:NOIP2014 洛谷 200005 int 题解 大值 back long push

题目https://www.luogu.com.cn/problem/P1351

我们可以发现,若点对 u,v 的距离为 2,则它们一定会经过一个中转点,因此我们考虑枚举中转点 k,然后枚举与 k 有直接边连接的两个点,按照题意统计答案即可。

#include<bits/stdc++.h>
using namespace std;
#pragma G++ optimisze(3,"Ofast","inline")
#define int long long
const int mod=10007;
int n,a[200005],ans,sum;
vector<int>v[200005];
signed main(){
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	cin>>n;
	for(int i=1,x,y;i<n;i++){
		cin>>x>>y;
		v[x].push_back(y);
		v[y].push_back(x);
	}
	for(int i=1;i<=n;i++){
		cin>>a[i];
	}
	for(int k=1;k<=n;k++){
		for(int i=0;i<v[k].size();i++){
			for(int j=i+1;j<v[k].size();j++){
				ans=max(ans,a[v[k][i]]*a[v[k][j]]);
				sum=(sum+a[v[k][i]]*a[v[k][j]])%mod;
			}
		}
	}
	cout<<ans<<' '<<(sum*2)%mod<<'\n';
	return 0;
}

将代码提交上去,不出意外地超时了(不超时那就有鬼了)。

怎么优化呢?

经过一番冥思苦想,我们发现,树中的最大值乘次大值的值一定是最大的

问题是总和怎么优化?

看看一个式子:

a\times b+a \times c+a\times d = a\times (b+c+d)

这就是小学数学中的乘法分配律(千万别跟我说你没学过啊喂)。

设 SUM_k 表示 k 的子树中的权值值和。

则可以计算出:sum=(sum+a_i\times (SUM_k-a_i))\bmod 10007

至于最大值和次大值和 SUM 可以用 DFS 求出。

实现

#include<bits/stdc++.h>
using namespace std;
#pragma G++ optimisze(3,"Ofast","inline")
#define int long long
const int mod=10007;
int n,a[200005],ans,sum,MAX[200005][2],SUM[200005];
vector<int>v[200005];
void dfs(int x,int fa){
	for(auto z:v[x]){
		SUM[x]+=a[z];
		if(MAX[x][0]<a[z]){
			MAX[x][1]=MAX[x][0];
			MAX[x][0]=a[z];
		}else if(MAX[x][1]<a[z]){
			MAX[x][1]=a[z];
		}
		if(z!=fa){
			dfs(z,x);
		}
	}
}
signed main(){
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	cin>>n;
	for(int i=1,x,y;i<n;i++){
		cin>>x>>y;
		v[x].push_back(y);
		v[y].push_back(x);
	}
	for(int i=1;i<=n;i++){
		cin>>a[i];
	}
	dfs(1,-1);
	for(int k=1;k<=n;k++){
		ans=max(ans,MAX[k][0]*MAX[k][1]);
		for(int i=0;i<v[k].size();i++){
			sum=(sum+a[v[k][i]]*(SUM[k]-a[v[k][i]]))%mod;
		}
	}
	cout<<ans<<' '<<sum<<'\n';
	return 0;
}

标签:NOIP2014,洛谷,200005,int,题解,大值,back,long,push
From: https://blog.csdn.net/ATION001/article/details/145288733

相关文章

  • 洛谷题单指南-线段树的进阶用法-P2839 [国家集训队] middle
    原题链接:https://www.luogu.com.cn/problem/P2839题意解读:求左端点在[a,b]之间,右端点在 [c,d]之间的子区间中,最大的中位数。解题思路:1、直男暴力法枚举左、右端点,然后排序计算中位数,这样的复杂度在n*n*logn,显然不可行。2、渣男巧妙法首先,要重新来看待何为中位数。设一段......
  • 【题解】Luogu P4340 [SHOI2016] 随机序列
    简单手摸后发现,答案就是这么一个式子:\[(3^{n-1}-3^{n-2})a_1+(3^{n-2}-3^{n-3})a_1a_2+\dots+(3^1-3^0)a_1a_2\dotsa_{n-1}+a_1a_2\dotsa_n\]啊当然证明也是好证的,对于\(a_1\)这一项,它后面放+或-都会对系数加一,而放*不会影响系数,因此系数就是总数的三分之二。其它前缀......
  • 题解:P3823 [NOI2017] 蚯蚓排队
    题目链接https://www.luogu.com.cn/problem/P3823分析先解决队伍的合并与分离问题。使用链表结构,分别维护每只蚯蚓的前驱和后继即可。然后考虑如何统计答案。可以对每只蚯蚓的“向后\(k\)数字串”使用字符串哈希的方式获得哈希值,再用一个哈希表存储每个哈希值出现的次数。对......
  • 2024 (ICPC) Jiangxi Provincial Contest I 题 Neuvillette Circling题解
    简单思路一个圆套中了几个点,如果不断缩小这个圆,那么最终的结果有两种有两个点卡住了这个圆,且这两点一定是直径有三个或者三个以上的点卡住了这个圆,圆心在这三个点围成的三角形的外接圆圆心。因此我们枚举两点作为直径,或者枚举三个点作为圆的内接三角形,求这个三角形的外接圆......
  • 2024 (ICPC) Jiangxi Provincial Contest L 题 Campus 题解
    简单思路首先对于所有的出口求一遍最短路,由于出口只会打开并关闭一次,所以大门的开启状态是相当有限的(最多大概30种),我们对于每一种状态直接暴力求答案最后输出即可。复杂度大概\(O(knlogn)\)参考代码#include<bits/stdc++.h>usingnamespacestd;typedeflonglongll;type......
  • 洛谷 P3397:地毯 ← “二维前缀和 + 二维差分”模板题
    【题目来源】https://www.luogu.com.cn/problem/P3397【题目描述】在n×n的格子上有m个地毯。给出这些地毯的信息,问每个点被多少个地毯覆盖。【输入格式】第一行,两个正整数n,m。意义如题所述。接下来m行,每行两个坐标(x1,y1)和(x2,y2),代表一块地毯,左上角......
  • Codeforces Round 998 (Div. 3) 部分题解
    写题解的时候这场在评测,就不放代码了。E.GraphComposition题意给两个无向简单图,对图\(1\)添加若干条边或删除若干条边,使得两图的连通性一致,最少需要变更多少条边。题解求出图\(2\)的连通性,考虑图\(1\)的所有边,若违背了图\(2\)联通性的要删除(图\(2\)不联通但图\(......
  • 20250120 T2 simu题解
    简单模拟(simu)【题目描述】给定$a_1,a_2,\ldots,a_n$和$b_1,b_2,\ldots,b_n$。对于所有整数$x\in[l,r]$,模拟以下过程并求出变量$res$的最终的值。res=0fori=1ton:ifx>=a[i]:x=x-a[i]res=res+b[i]【输入格式】......
  • 「题解」二进制与一
    传送门:水滴、洛谷题目大意:给定一个正整数$n$,给出操作次数$p$。每次操作让$n$加上一个非负整数$x$,使得$n$的第$k$位为$0$(从右往左数)。如果本身为$1$就不用操作。且每次操作$n+x$回影响后续操作。问$x$的和是多少。首先我们要知道,判断$n$的第$k$位是否为$......
  • 题解:CF580B Kefa and Company
    CF580BKefaandCompany前言。其实本题与这道题极为相似,所以建议降橙。思路因为输入顺序不影响就结果,所以可以先给\(a\)按照工资从小到打排序一下序(这里\(a\)使用MAP)。然后再使用尺取法,只要\(a_{r+1}\)的值减\(a_l\)的值\(\ltk\)就将\(r\)加\(1\)。然后发现每......