C. Multiples of Length 思维构造

tech2022-07-06  267

传送门

题意

给你一个长度为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; }
最新回复(0)