C. Sum on Subarrays

链接:https://codeforces.com/problemset/problem/1809/C
https://www.luogu.com.cn/problem/CF1809C
题目:
熬过了期末月,开始算法复健(ง •_•)ง
刚开始没转过弯来,以为必须要拆开来,后面想到好办法:取1~kx,其中kx满足(1+kx)*kx/2<=k,然后剩下的就填在末尾,补充剩下的不足kx+1的部分。
为什么要从2开始?因为注意到题目说的是正数和负数,不包括0,如果从1开始这里会有间断。
结合下图理解:

代码:

#define _CRT_SECURE_NO_WARNINGS 
#include<iostream>
#include<vector>
#include<algorithm>
#include<math.h>
#include<sstream>
#include<string>
#include<string.h>
#include<iomanip>
#include<stdlib.h>
#include<map>
#include<queue>
#include<limits.h>
#include<climits>
#include<fstream>
#include<stack>
typedef long long ll;
using namespace std;
const int inf = -1000 , N=31;
int fx[N];
void init()
{
	for (int i = 1; i <= N; i++)
		fx[i] = i * (i + 1) / 2;
	return;
}
int ans[N];
void reset(ll n)
{
	for (int i = 1; i <= n; i++)ans[i] = -1000;
}

int main()
{
	ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
	ll n, k, t;
	cin >> t; init();
	while (t--)
	{
		cin >> n >> k;
		reset(n);
		int l = 1, r = n;
		if(k)
		{
			while (l < r)
			{
				int m = l + (r - l + 1) / 2;
				if (fx[m] >= k)r = m - 1;
				else l = m;
			}
			for (int i = 1; i <= l; i++)ans[i] = i + 1;
			if (k != fx[l])
			{
				ll tem = k - fx[l];
				if (tem == l)ans[l + 1] = -l;
				else
				{
					ans[l + 1] = -(l + tem + 3) * (l - tem) / 2 - 1;
				}

			}
		}
		for (int i = 1; i <= n; i++)cout << ans[i] << ' ';
		cout << '\n';
	}

	return 0;
}

posted on 2024-06-26 22:50  WHUStar  阅读(4)  评论(0编辑  收藏  举报