传送门
题意
给你一个长度为n的数组,让你进行三次操作,选择一个l到r的区间,这段长度为r - l,然后对于这段区间内的每一个数字,你都可以加上或者减去这段长度的倍数,要求三次操作结束之后,数组中每个元素都为0,求出这三次操作
分析
这道题首先我们可以把这个数组中的每一个元素都变成n的倍数,然后一起消除就可以了
然后我们选择n - 1这个点,把前n - 1个数字都加上(n - 1)* a[i],这样每一位数字都变成了n * a[i],也就是a[i] 的n倍,最后的a[n]因为长度为1,所以也加上(n - 1)* a[n],最后整体减去n * a[i]即可
注意两点
- n == 1的时候需要特判
- n * a[I]可能会爆int,需要用1ll * 来处理
代码
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <queue>
#include <cstring>
#define debug(x) cout<<#x<<":"<<x<<endl;
#define _CRT_SECURE_NO_WARNINGS
#pragma GCC optimize("Ofast","unroll-loops","omit-frame-pointer","inline")
#pragma GCC option("arch=native","tune=native","no-zero-upper")
#pragma GCC target("avx2")
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> PII;
const int INF = 0x3f3f3f3f;
const int N = 1e5 + 10;
int a[N];
int n;
void ans(){
printf("%d %d\n",1,n - 1);
for(int i = 1;i < n;i++)
printf("%lld ",(1ll * n - 1) * a[i]);
puts("");
printf("%d %d\n",n,n);
printf("%lld\n",1ll * (n - 1) * a[n]);
printf("%d %d\n",1,n);
for(int i = 1;i <= n;i++)
printf("%lld ",-(1ll * n * a[i]));
puts("");
}
int main(){
scanf("%d",&n);
for(int i = 1;i <= n;i++) scanf("%d",&a[i]);
if(n != 1) ans();
else{
puts("1 1");
cout << -a[1] << endl;
puts("1 1");
puts("0");
puts("1 1");
puts("0");
}
return 0;
}