【洛谷 11 月月赛 I & MCOI Round 3 Div.2】【数学】村国

38 篇文章 0 订阅
题目背景

What   did   this   player   dream? \texttt{What did this player dream?} What did this player dream?

他梦见了什么?

This   player   dreamed   of   sunlight   and   trees.Of   fire   and   water. \texttt{This player dreamed of sunlight and trees.Of fire and water.} This player dreamed of sunlight and trees.Of fire and water.

他梦见了阳光与树木。梦见了火与水。

It   dreamed   it   created.   And   it   dreamed   it   destroyed.   It   dreamed   it   hunted, \texttt{It dreamed it created. And it dreamed it destroyed. It dreamed it hunted,} It dreamed it created. And it dreamed it destroyed. It dreamed it hunted, and   was   hunted.   It   dreamed   of   shelter. \texttt{and was hunted. It dreamed of shelter.} and was hunted. It dreamed of shelter.
他梦见他的创造,亦梦见他毁灭。它梦见他在狩猎,亦梦见被猎捕。他梦见温馨的居所。

Hah,   the   original   interface.   A   million   years   old,   and   it   still   works.But \texttt{Hah, the original interface. A million years old, and it still works.But} Hah, the original interface. A million years old, and it still works.But   what   true   structure   did   this   player   create,   in   the   reality   behind   the   screen? \texttt{ what true structure did this player create, in the reality behind the screen?}  what true structure did this player create, in the reality behind the screen?

哎,那原始的界面。经历百万年的岁月,它依然在工作。只是他在屏幕后的真实里,到底创造了什么真实的世界呢?

题目描述

C 国一共有 N N N个村庄, N − 1 N-1 N1条道路。这些道路都可以双向通行。保证小 S 可以从一座村庄到其他任何一座村庄。这 N N N个村庄编号为 1 1 1 N N N

刚开始小 S 对第 i i i个村庄的好感值为 A i A_i Ai。小 S 的假期一共有 M M M天,他会在 C 国旅行一共 M M M天。每一天他会选择来到当前好感值最高的村庄。如果有好感值相同的村庄,他会选择编号最小的村庄。假设这一天他来到村庄 X X X,那么这一天结束后,与村庄 X X X直接相邻所有村庄的好感值都会增加 1 1 1。即能从 X X X出发仅经过一条道路到达的村庄好感值会增加 1 1 1。因为小 S 已经在村庄 X X X待过一天了,所以这一天结束后村庄 X X X的好感值并不会增加。

现在小 S 想要知道经过 M M M天的旅行后好感值最高的村庄。

如果有多个好感值最高的村庄,输出编号最小的。

输入格式

本题单个测试点包含多组测试数据。
第一行一个正整数 T T T表示数据组数。
对于每组数据:
第一行包括两个正整数 N , M N,M N,M,表示村庄个数和旅行天数。
接下来一行 N N N个整数,第 i i i个整数表示第 i i i座村庄的好感值 A i A_i Ai
接下来 N − 1 N-1 N1行。每行两个整数 x , y x,y x,y表示村庄 x x x和村庄 y y y之间有一条双向通行的道路。

输出格式

一个整数表示 M M M天结束后好感值最高的村庄的编号。如果有多个好感值最高的村庄,输出编号最小的。

输入输出样例
输入 #1
2
2 3
2 6
1 2
3 5
2 6 4
1 3
2 3
输出 #1
2
3
说明/提示
样例说明

对于第一组数据,小 S 在 2 2 2 号村庄旅行了 3 3 3天,结束时村庄 1 , 2 1,2 1,2的好感值分别为 5 , 6 5,6 5,6。所以答案输出 2 2 2

对于第二组数据,结束时三个村庄的好感值分别为 3 , 7 , 8 3,7,8 3,7,8,所以答案输出 3 3 3

数据规模与约定

对于 100 % 100\% 100%的数据, 1 ≤ N ≤ 2 × 1 0 6 1 \le N\le 2\times10^6 1N2×106
1 ≤ M ≤ 1 0 18 , 1 ≤ A i ≤ 2 31 − 1 , 1 ≤ T ≤ 10 1 \le M\le10^{18},1 \le A_i\le2^{31}-1,1 \le T\le10 1M10181Ai23111T10

测试点编号 A i ≤ A_i\le Ai ∑ N ≤ \sum N \le N M ≤ M \le M测试点分值
11020105
2 1 0 2 10^2 102 2 × 1 0 2 2×10^2 2×102 1 0 2 10^2 102 10 10 10
3 1 0 3 10^3 103 2 × 1 0 3 2×10^3 2×103 1 0 3 10^3 103 15 15 15
4 1 0 5 10^5 105 2 × 1 0 5 2×10^5 2×105 1 0 5 10^5 105 15 15 15
5 2 × 1 0 6 2×10^6 2×106 45 45 45
提示

本题输入量较大,请使用较快的读入方式。


解题思路

请,动动小手指,多列列一些数据
就会发现,其实最终真正会有改变的只有两个点:1、初始好感度最大的点 2、与它相连的最大的点


#include <iostream>
#include <cstdio>

using namespace std;

long long s[2001000], T, n, m, x, y, t1, t2, maxx, cmax, k;

int main(){
	scanf ("%lld", &T);
	while (T--)
	{
		scanf ("%lld%lld", &n, &m);
		
		maxx = 0, cmax = 0, t2 = t1 = n + 1;
		for (int i = 1; i <= n; i++)
		{
			scanf ("%lld", &s[i]);
			if (s[i] > maxx)
			    maxx = s[i], t1 = i;//记录初始好感度最大的点
		}
		for (int i = 1; i < n; i++)
		{
			scanf ("%lld%lld", &x, &y);
			if (x == t1)
			    if (s[y] > cmax || (s[y] == cmax && y < t2))
			        cmax = s[y], t2 = y;
			if (y == t1)
			    if (s[x] > cmax || (s[x] == cmax && x < t2))
			        cmax = s[x], t2 = x;
			//与它相连的点中,好感度最高的点
		}  
		if (n == 1)//如果只有一个点,肯定是1点好感度最高
		{
		    printf ("1\n");
			continue;
		}
		//k:t2过k天就比t1更优了
		k = s[t1] - s[t2];
		if (t2 > t1)
			k++;//如果t2标号更大,那么天数还要加一
		if (k > m) printf ("%lld\n", t1);//如果m天t2都不能比t1优,输出t1
			else
		if ((m - k) % 2) printf ("%lld\n", t1);//剩下的天数,单数t1优,偶数t2优
			else printf ("%lld\n", t2);
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,这是一个比较简单的数学题,可以用矩阵速幂求解。以下是 C++ 代码实现: ```c++ #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; typedef long long LL; const int MAXN = 2; const int MOD = 1e9 + 7; struct Matrix { LL m[MAXN][MAXN]; Matrix() { memset(m, 0, sizeof(m)); } Matrix operator * (const Matrix& b) const { Matrix c; for (int i = 0; i < MAXN; ++i) { for (int j = 0; j < MAXN; ++j) { for (int k = 0; k < MAXN; ++k) { c.m[i][j] = (c.m[i][j] + m[i][k] * b.m[k][j]) % MOD; } } } return c; } } base, res; Matrix qpow(Matrix a, int b) { Matrix ans; for (int i = 0; i < MAXN; ++i) { ans.m[i][i] = 1; } while (b) { if (b & 1) { ans = ans * a; } a = a * a; b >>= 1; } return ans; } LL gcd(LL a, LL b) { return b == 0 ? a : gcd(b, a % b); } int main() { LL a, b, n; cin >> a >> b >> n; if (n == 1) { cout << a << endl; } else if (n == 2) { cout << b << endl; } else { base.m[0][0] = base.m[0][1] = base.m[1][0] = 1; res = qpow(base, n - 2); LL ans = gcd(a * res.m[0][0] % MOD + b * res.m[1][0] % MOD, b * res.m[1][0] % MOD + b * res.m[1][1] % MOD); cout << ans << endl; } return 0; } ``` 在这段代码中,我们定义了一个 `Matrix` 结构体,它表示一个 $2\times2$ 的矩阵。其中重载了 `*` 运算符,实现了矩阵乘法。 然后,我们定义了一个矩阵速幂函数 `qpow`,用于求解矩阵的 $n$ 次方。 最后,在 `main` 函数中,我们通过速幂求出矩阵 $base$ 的 $n-2$ 次方,然后根据题目要求求出 $\gcd(F_N, F_{N+1})$ 并输出即可。 需要注意的是,当 $n=1$ 或 $n=2$ 时,直接输出 $a$ 或 $b$ 即可。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值