[题解]CF1704D Magical Array
题意
给定 个长度为 的数组,对于每一个数组选择下面任意一种操作进行若干次(操作二只能被一个数组选出)。
- 。
- 。
最后输出选择操作二的数组的编号,及其使用操作二的次数。
思路
我们不难发现一个普遍性的规律。
如果已知操作一号的数组,操作前和操作后的 是不变的。
原因如下:
我们直接看有变化的部分即可。
操作前:。
操作后:。
我们将上式化简:。
发现两式相等,证毕。
我们可以通过这一点,用 维护一个 的前缀和,来寻找出这个与众不同的数组。
这里还有一个奇妙的规律,需要大家去体会体会。
就是,那个选择操作二的数组的操作次数一定是:。
因为,我们上文说过,选择操作一的 不变,那么,我们再根据上面的推导过程再次推导一遍可以发现,没操作一次操作二,对于我们的 每次加 。
因此,我们就得出了上面的结论。
Code
#include <bits/stdc++.h>
#define int long long
#define re register
using namespace std;
const int N = 1e5 + 10,inf = 1e18 + 10;
int T,n,m;
int s[N];
inline int read(){
int r = 0,w = 1;
char c = getchar();
while (c < '0' || c > '9'){
if (c == '-') w = -1;
c = getchar();
}
while (c >= '0' && c <= '9'){
r = (r << 3) + (r << 1) + (c ^ 48);
c = getchar();
}
return r * w;
}
signed main(){
T = read();
while (T--){
int Max = -inf,Min = inf;
memset(s,0,sizeof(s));//初始化
n = read();
m = read();
for (re int i = 1;i <= n;i++){
for (re int j = 1;j <= m;j++){
int x;
x = read();
s[i] += x * j;//前缀和
}
Max = max(Max,s[i]);//最大值
Min = min(Min,s[i]);//最小值
}
for (re int i = 1;i <= n;i++){
if (Max == s[i]){//输出答案
printf("%lld %lld\n",i,Max - Min);
break;
}
}
}
return 0;
}
作者:WaterSun
出处:https://www.cnblogs.com/WaterSun/p/18264797
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
分类:
题解
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 一文读懂知识蒸馏
· 终于写完轮子一部分:tcp代理 了,记录一下