标签:一个 names 区别 second const ++i top efi auto
题意:有一个长度为\(n\)元素均为\(0\)的序列,进行\(n\)次操作构造出一个新序列\(a\):每次选择最长的连续为\(0\)的区间\([l,r]\),使得第\(i\)次操作时,\(a[\frac{l+r}{2}]=i\)(下取整),求\(a\).
题解:刚开始我打算用归并分治的思想来写,但是发现左区间递归不到,然后就gg了.
? 之后才发现这题用_优先队列_直接模拟就过了,题目就不说了,这儿讲一下优先队列.
优先队列与队列的区别在于,优先队列是按照某种优先级来决定谁在队头,C++默认它是一个大根堆,但是我们往往需要自己来定义优先级,所以我们就可以用一个结构体来重载运算符,再结合堆的性质来理解就好了.
代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <stack>
#include <queue>
#include <vector>
#include <map>
#include <set>
#include <unordered_set>
#include <unordered_map>
#define ll long long
#define fi first
#define se second
#define pb push_back
#define me memset
const int N = 1e6 + 10;
const int mod = 1e9 + 7;
using namespace std;
typedef pair<int,int> PII;
typedef pair<long,long> PLL;
int t;
int n;
int ans[N];
int cnt;
struct Node{
int l,r;
bool operator < (const Node &w)const{
if(r-l==w.r-w.l) return l>w.l;
else return r-l<w.r-w.l;
}
};
int main() {
ios::sync_with_stdio(false);
cin>>t;
while(t--){
cin>>n;
cnt=0;
priority_queue<Node> q;
q.push({1,n});
while(!q.empty()){
auto cmp=q.top();
q.pop();
int l=cmp.l;
int r=cmp.r;
int mid=l+r>>1;
ans[mid]=++cnt;
if(l!=mid) q.push({l,mid-1});
if(r!=mid) q.push({mid+1,r});
}
for(int i=1;i<=n;++i) printf("%d ",ans[i]);
puts("");
}
return 0;
}
Codeforces Round #642 (Div. 3) D. Constructing the Array (优先队列)
标签:一个 names 区别 second const ++i top efi auto
原文地址:https://www.cnblogs.com/lr599909928/p/12896572.html