1397C. Multiples of Length(构造)

其实不难想,主要看你想的方向对不对

思路 ( ) \color{Red}(想看做法可以直接跳过这部分)

a i 0 a_i想变成0

l e n , 使 l e n 一定是最后选择了某个长len得区间,使得自己是len的倍数

3 n 0 , l e n 但是要在3次操作把n个数变成0,说明这个len区间必须很大很大

n , ? 有没有可能把所有数先变成n的倍数,然后一次性消除掉呢?

a i n , [ 1 , n ] 因为一开始a_i不一定是n的倍数,所以选择[1,n]是没有意义的

[ 1 , n 1 ] , n 1 n ? 但是选择[1,n-1],加上n-1的若干倍不久可以变成n的倍数了吗?

做法

, [ 1 , n 1 ] n 第一次操作的目的,把[1,n-1]变成n的倍数

a i , k ( n 1 ) a i + k ( n 1 ) 所以对于a_i,设加上了k(n-1)变成a_i+k(n-1)

k n + a i k , k = a i 也就是kn+a_i-k,所以k=a_i

a i a i ( n 1 ) n ! ! 那么只要给每个a_i加上a_i(n-1)就可以变成n的倍数!!

[ n , n ] 第二次操作把[n,n]的数变成倍数

[ 1 , n ] 0 ( n ) 第三次操作把[1,n]都变成0(因为前面都变成了n的倍数)

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int maxn=2e5+10;
int t,n,a[maxn],b[maxn];
signed main()
{
	cin >> n;
	for(int i=1;i<=n;i++)	cin >> a[i];
	if( n==1 )
	{
		cout << 1 << " " << 1 << '\n';
		cout << -a[1] << '\n';
		for(int i=2;i<=3;i++)
		{
			cout << 1 << " " << 1 << '\n';
			cout << 0 << '\n';
		}
		return 0;
	}
	cout << 1 << " " << n-1 << "\n";
	for(int i=1;i<=n-1;i++)
	{
		cout << (n-1)*a[i] << " ";
		a[i]+=(n-1)*a[i];
	}
	cout << endl;
	cout << n << " " << n << '\n';
	cout << -a[n] << '\n';
	cout << 1 << " " << n << '\n';
	for(int i=1;i<n;i++)
		cout << -a[i] << " ";
	cout << 0;
}

猜你喜欢

转载自blog.csdn.net/jziwjxjd/article/details/108314021