当前位置: 代码迷 >> 综合 >> Codeforces D. Constructing the Array (最大连续区间 / 优先队列) (Round #642 Div.3)
  详细解决方案

Codeforces D. Constructing the Array (最大连续区间 / 优先队列) (Round #642 Div.3)

热度:33   发布时间:2023-12-22 13:42:25.0

传送门

题意: 现有一个长度为n的初始数组a(其值全为0),对其进行n次操作。每次从左往右选取其连续为0的最大子段进行如下两类操作:

  • 若r - l + 1为偶数,那么a[(l + r) / 2] := i.
  • 若r - l + 1为奇数,那么a[(l + r - 1) / 2] := i.

其中 i 表示第 i 次操作。最后输出答案数组a(该数组存在且唯一)。
在这里插入图片描述

思路:

  • 可以利用机构图定义一个新类型,该类型代表连续为0的小区间,其具有区间的左右边界l,r和区间的长度len.
  • 利用优先队列排序,按照长度降序排列,长度相等的按照左边界l的升序排列。
  • 每次取队头进行处理,每次找到相应的a[pos]赋值为 i ,再将pos分成的两个新的连续0子段加入队列中。

代码实现:

#include<bits/stdc++.h>
#define endl '\n'
#define null NULL
#define ll long long
#define int long long
#define pii pair<int, int>
#define lowbit(x) (x &(-x))
#define ls(x) x<<1
#define rs(x) (x<<1+1)
#define me(ar) memset(ar, 0, sizeof ar)
#define mem(ar,num) memset(ar, num, sizeof ar)
#define rp(i, n) for(int i = 0, i < n; i ++)
#define rep(i, a, n) for(int i = a; i <= n; i ++)
#define pre(i, n, a) for(int i = n; i >= a; i --)
#define IOS ios::sync_with_stdio(0); cin.tie(0);cout.tie(0);
const int way[4][2] = {
    {
    1, 0}, {
    -1, 0}, {
    0, 1}, {
    0, -1}};
using namespace std;
const int  inf = 0x7fffffff;
const double PI = acos(-1.0);
const double eps = 1e-6;
const ll   mod = 1e9 + 7;
const int  N = 2e5 + 5;int t, n, a[N];struct node{
    int l,r,len;//重载运算符bool operator < (const node&next )const{
    if(len == next.len)	return l > next.l;return len < next.len;}
};priority_queue<node> q;signed main()
{
    cin >> t;while(t --){
    cin >> n;while(!q.empty()) q.pop();q.push((node){
    1, n, n});int cnt = 0;while(true){
    //取出队头node top = q.top(); q.pop();int l = top.l, r = top.r, pos;//找到相应位置赋值if((r - l + 1) % 2){
    a[(l + r) >> 1] = ++ cnt;pos = (l + r) >> 1;}else{
    a[(l + r - 1) >> 1] = ++ cnt;pos = (l + r - 1) >> 1;}if(cnt == n) break; //n次操作已进行完//将新产生的子段加入队列if(pos - 1 >= l) q.push((node){
    l, pos - 1, pos - l});if(r >= pos + 1) q.push((node){
    pos + 1, r, r - pos});}//最后自己输出答案数组for(int i = 1; i <= n; i ++)cout << a[i] << " ";cout << endl;}return 0;
}
  相关解决方案