C. Multiples of Length 思维构造

传送门

题意

给你一个长度为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]即可

注意两点

  1. n == 1的时候需要特判
  2. 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;
}



猜你喜欢

转载自blog.csdn.net/tlyzxc/article/details/108368872