题目描述
For a number t denote as h(t) maximal k such that t is divisible by 2k. For example, h(24)=3, h(5)=0. Let l(t)=2h(t), for example, l(24)=8, l(5)=1.
Consider array a[1],a[2],…,a[n] of integer numbers. Fenwick tree for this array is the array b[1],b[2],…,b[n] such that
b[i]=∑j=i−l(i)+1ia[j]
So
b[1]=a[1],
b[2]=a[1]+a[2],
b[3]=a[3],
b[4]=a[1]+a[2]+a[3]+a[4],
b[5]=a[5],
b[6]=a[5]+a[6],
…
For example, the Fenwick tree for the array a=(3,−1,4,1,−5,9) is the array b=(3,2,4,7,−5,4).
Let us call an array self-fenwick if it coincides with its Fenwick tree. For example, the array above is not self-fenwick, but the array a=(0,−1,1,1,0,9) is self-fenwick.
You are given an array a. You are allowed to change values of some elements without changing their order to get a new array a′ which must be self-fenwick. Find the way to do it by changing as few elements as possible.
输入格式
The first line of the input file contains n ― the number of elements in the array (1≤n≤100 000). The second line contains n integer numbers ― the elements of the array. The elements do not exceed 109 by their absolute values.
输出格式
Output n numbers ― the elements of the array a′. If there are several solutions, output any one.
样例
input
6 3 -1 4 1 -5 9output
0 -1 1 1 0 9
思路:这道题其实只是利用了树状数组的定义,但实际解题和树状数组的应用没有太大关系。。。可以根据题中描述的递推式,将a[i]=b[i]这个条件代入,得到下标为偶数的元素可以为任意值,则为了最少次数的修改原数组,下标为偶数的元素我们保持不变;下标为奇数的元素则可以根据前面确定下来的奇数元素和原数组中的偶数元素推出。根据样例举例:b[2]=a[1]+a[2],由于a[2]=b[2],所以a[1]只能为0,a[2]不变为-1 ;b[4]=a[1]+a[2]+a[3]+a[4],其中a[1],a[2]已知,且a[1]+a[2]+a[3]=0,则a[3]=1,以此类推。代码如下:
#include <iostream>
#include <vector>
using namespace std;
typedef long long LL;
int lowbit(int x)//帮助寻找数组b的起始下标(树状数组定义)
{
return x&(-x);
}
int main()
{
int n;
vector<LL> ele;
cin>>n;
for(int i=0; i<n; ++i){
LL x;
cin>>x;
ele.push_back(x);
}
for(int i=1; i<n; i+=2){//只修改下标为奇数的元素
LL sum=0;
for(int j=i-lowbit(i+1)+2; j<i; ++j)
sum -= ele[j-1];
ele[i-1] = sum;
}
for(auto itr = ele.begin(); itr<ele.end(); ++itr){
cout<<*itr;
if(itr != ele.end())
cout<<' ';
}
return 0;
}