CF1704D Magical Array - 构造 -
题目链接:https://codeforces.com/contest/1704/problem/D
题意:
有n个序列,初始都一样,选定某一个序列\(c_k\),对\(c_k\)做至少一次操作②,对除\(c_k\)以外的每一个数列至少做一次操作①,给出最后得到的\(n\)个数列,问\(k\)和操作②的次数
操作①:选定\(2 \leq i,j \leq m\)(m为序列长度),\(c_{i-1}和c_{j+1}-1\),\(c_{i}和c_{j}+1\)
操作①:选定\(2 \leq i,j \leq m-1\),\(c_{i-1}和c_{j+2}-1\),\(c_{i}和c_{j}+1\)
题解:
设\(F(k)=c_k[i]*i\)
对于操作①,计算\(F(k)\)的新值为\((c_k[i-1]+1)*(i-1)+(c_k[i]-1)*i+(c_k[j]-1)*j+(c_k[j+1]+1)*(j+1)\)
对应的旧值为\((c_k[i-1])*(i-1)+(c_k[i])*i+(c_k[j])*j+(c_k[j+1])*(j+1)\)
观察可知,二者结果相等
同理对于操作②,我们发现其新的结果恰好多了一个1(\((j+1)\)变成了\((j+2)\),结果多1)
于是我们统计一下每个数列对应的\(F(k)\)值即可
代码:
// by Balloons
#include <cstdio>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
#define mpr make_pair
#define debug() cerr<<"Madoka"<<endl
#define rep(i,a,b) for(int (i)=(a);(i)<=(b);(i)++)
using namespace std;
typedef long long LL;
#define int LL
const int inf = 1e9,maxn=1e5 + 5;
int n,m;
void solve(){
scanf("%I64d%I64d",&n,&m);
int mxx = -1e18,mnn = 1e18,p;
for(int i=1;i<=n;i++){
int mx=0;
for(int j=1;j<=m;j++){
int t;scanf("%I64d",&t);
mx += t*j;
}
if(mxx < mx)p = i;
mxx = max(mxx, mx);
mnn = min(mnn, mx);
}
printf("%I64d %I64d\n",p,mxx - mnn);
}
signed main(){
int te;scanf("%I64d",&te);
while(te --)solve();
return 0;
}