B. Find The Array(构造题

B. Find The Array
题意:
给定一个长度为 n n n 的序列 a a a a i < = 1 0 9 a_i<=10^9 ai<=109,设和为 S S S
定义一个美丽序列 b b b

  1. 1 < = b i < = 1 0 9 1<=b_i<=10^9 1<=bi<=109
  2. 对于每一个相邻的 b i , b i + 1 b_i,b_{i+1} bi,bi+1 满足 b i ∣ b i + 1 b_i|b_{i+1} bibi+1 或者 b i + 1 ∣ b i b_{i+1}|b_i bi+1bi
  3. 2 ∗ ∑ i = 1 n ∣ a i − b i ∣ < = S 2*\sum_{i=1}^n|a_i-b_i|<=S 2i=1naibi<=S

输出任意一个美丽序列 b b b
思路:
大佬的奇妙题解
构造一个 2 2 2 的幂的序列 b b b 即可满足条件 2 2 2
第三个性质可以转化为这样一个充分条件 ∣ a i − 2 k ∣ < = a i 2   ( 1 < = i < = n ) |a_i-2^k|<=\frac{a_i}{2} \ (1<=i<=n) ai2k<=2ai (1<=i<=n)
那么如果 ∣ x − 2 k ∣ < = x 2 |x-2^k|<=\frac{x}{2} x2k<=2x 对于所有的 x x x 都能找到对应的 k k k 满足不等式即可构造
证明不会
std:
把序列 n n n 按照奇偶性分成两堆,那么两堆和 S 1 > = S S_1>=S S1>=S S 2 < = S S_2<=S S2<=S,然后缺奇或缺偶的位置放 1 1 1,这样就能满足条件 2 2 2
1 , a 2 , 1 , a 4 . . . 1,a_2,1,a_4... 1,a2,1,a4...
求和为 ( a 1 − 1 ) + 0 + ( a 3 − 1 ) + 0 + . . . (a_1-1)+0+(a_3-1)+0+... (a11)+0+(a31)+0+...
a 1 , 1 , a 3 , 1... a_1,1,a_3,1... a1,1,a3,1...
求和为 0 + ( a 2 − 1 ) + 0 + ( a 3 − 1 ) + . . . 0+(a_2-1)+0+(a_3-1)+... 0+(a21)+0+(a31)+...
总结一下就是替换掉奇数,那么和就由奇数贡献,偶数同理
因此替换掉和更小的一方即可
这样构造的两个奇偶相间的序列必然有一个满足条件 3 3 3
code:

#include<bits/stdc++.h>
#define endl '\n'
#define ll long long
#define ull unsigned long long
#define ld long double
#define all(x) x.begin(), x.end()
#define eps 1e-6
using namespace std;
const int maxn = 2e6 + 9;
const int mod = 1e9 + 7;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
ll n, m;
int a[maxn];

void work()
{
	cin >> n;
	ll sum = 0, odd = 0;
	for(int i = 1; i <= n; ++i) cin >> a[i], odd += i & 1 ? a[i] : 0, sum += a[i];
	if(odd < sum - odd){
		for(int i = 1; i <= n; ++i){
			if(i & 1) cout << 1 << " ";
			else cout << a[i] << " ";
		}
	}
	else{
		for(int i = 1; i <= n; ++i){
			if(i & 1) cout << a[i] << " ";
			else cout << 1 << " ";
		}
	}
	cout << endl;
}

int main()
{
	ios::sync_with_stdio(0);
	int TT;cin>>TT;while(TT--)
	work();
	return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值