题意是给你一个数n,让你构造一串序列a,使得a的极差==根号下的求和,问你构造的序列是什么
分析:
最近写题的思维度有些下降,并不是说这题我写不出,而是因为当时思考的角度就是错的,很离谱。这两天写题的精神状态不佳,思路乱的一塌糊涂,很怪
以下思路来源于Codeforces Round #836 (Div. 2) A-E - 知乎 (zhihu.com)
这题的构造可以不同,其实有这样的一个关系的,可以推一推关系式中的联系
因为是极差要和求和之后开根号相等
所以我们可以构造极差为2*n(n好像也行?)
所以求和就是4*n*n
所以先令每一个数为4*n,所以容易看出a[1]为3*n,a[n]为5*n
因为极差是2*n,所以首尾两个数之间所填的数是肯定不会超出的
下面采用多退少补原则
前面一半每次减去k(k递增)
后面一半对应着加上k
这样就能保证总和是4*n*n,极差是2*n
因为是对称,所以从中间往两边就可以。其实是不好从前往后的去填数,不好保证开头和最后结尾是不是在(a[1],a[n])的范围里面。
下面是代码:
//#pragma GCC optimize(1)
//#pragma GCC optimize(2)
//#pragma GCC optimize(3,"Ofast","inline")
#define IOS ios::sync_with_stdio(false), cin.tie(0);
#include<iostream>
#include<map>
#include<set>
#include<cstdio>
#include<cstring>
#include<vector>
#include<stack>
#include<algorithm>
#include<cmath>
#include<queue>
#include<deque>
using namespace std;
#define int long long
typedef long long ll;
typedef pair<int,int> PAII;
const int N=2e6+10,M=5050,INF=1e18,mod=998244353;
int a[N];
signed main(){
//IOS;
int T;
//T=1;
cin>>T;
while(T--)
{
int n;
cin>>n;
for(int i=1;i<=n;i++) a[i]=4*n;
int x=n/2;
int k=0;
for(int i=x;i>1;i--)
{
k++;
a[i]-=k;
}
a[1]=3*n;
a[n]=5*n;
if(n&1) x+=2;
else x++;
k=0;
for(int i=x;i<n;i++)
{
k++;
a[i]+=k;
}
for(int i=1;i<=n;i++) cout<<a[i]<<" ";
cout<<"\n";
}
return 0;
}
/*
*/