传送门
题意
给你一个长度为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;
}