E. Permutation by Sum
题目大意
给你一个数n,和一个l~r的区间,和一个目标值,问你能让1到的n的排列,使得l至的r之间的和为目标值,如果找不到输出-1
思路
首先一个这个区间有个最大值n,n-1…n-r+l和一个最小值1,2,3,…r-l+1,目标值在这个区间内是合法的,否则就输出-1,如果合法那么,先找目标值和区间最小和的差值,然后将这个差值除以这个区间元素的个数,然后将这个这个值,加到最小值中的每一位元素上,如有有余数,需要重新加上,然后在区间前的元素先输出,然后输出区间元素,最后输出区间后的元素注意每次输出需要标记一下
#include <bits/stdc++.h>
#pragma GCC optimize("Ofast")
#pragma GCC target("avx,avx2,fma")
#pragma GCC optimization ("unroll-loops")
using namespace std;
#define ll long long
#define sl(n) scanf("%lld",&n)
#define pl(n) printf("%lld",n)
#define sdf(n) scanf("%lf",&n)
#define pdf(n) printf("%.lf",n)
#define pE printf("\n")
#define ull unsigned long long
#define pb push_back
#define debug(a) cout<<a<<"??"
#define me(a) memset(a,0,sizeof(a))
#define pre(n) for(ll i=1;i<=n;i++)
#define rep(n) for(ll i=n;i>=1;i--)
#define ph push
#define pi pair<ll,ll>
#define fi first
#define se second
const ll mod = 1e9 + 7;
ll a[600];
int main()
{
ll t, i, j;
sl(t);
while (t--)
{
map<ll, ll>mp;
me(a);
ll suml, sumr, n, l, r, pos;
sl(n), sl(l), sl(r), sl(pos);
ll cnt = r - l + 1;
j=1;
for ( i = l; i <= r; i++)a[i] = j++;
suml = cnt * (1 + cnt) / 2, sumr = cnt * (2 * n - cnt + 1) / 2;
if (pos <= sumr && pos >= suml)
{
ll dif = pos - suml;
ll wi = dif / cnt, mm = dif % cnt;
for (i = l; i <= r; i++)
{
a[i] += wi;
mp[a[i]]++;
}
if (mm)
{
for (i = l; i <= r; i++)
{
if (!mp[a[i] + mm] && a[i] + mm <= n)
{
mp[a[i]] = 0;
a[i] += mm;
mp[a[i]]++;
break;
}
}
}
j = 0;
for (i = 1; i <= n && j<l-1; i++)
{
if (!mp[i])
{
j++;
cout << i << ' ';
mp[i]++;
}
}
for (i = l; i <= r; i++)cout << a[i] << ' ';
for(i = 1; i <= n; i++)
{
if (!mp[i])cout << i << ' ';
}
puts("");
}
else puts("-1");
}
return 0;
}