一、Priority Queue
直接用priority queue实现
#include <bits/stdc++.h>
using namespace std;
priority_queue<int> q;
int main(){
string a;
int b;
while(1){
cin>>a;
if(a=="insert"){
cin>>b;
q.push(b);
}
else if (a=="extract"){
int t=q.top();
cout<<t<<endl;
q.pop();
}
else if(a=="end")break;
}
}
二、ST表
直接使用st表
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5+5,T = log2(N)+1;
int st[N][T],log_2[N];
int main(){
int n,m;
scanf("%d %d", &n, &m);
log_2[1]=0;
for(int i=2;i<=n;i++){
log_2[i]=log_2[i/2]+1;
}
for(int i=1;i<=n;i++){
scanf("%d", &st[i][0]);
}
for(int j=1;j<=log_2[n];j++){
for(int i=1;i+(1<<j)-1<=n;i++){
st[i][j]=max(st[i][j-1],st[i+(1<<(j-1))][j-1]);
}
}
int l,r;
for(int i=1;i<=m;i++){
scanf("%d %d", &l, &r);
int s=log_2[r-l+1];
printf("%d\n", max(st[l][s], st[r - (1 << s) + 1][s]));
}
return 0;
}
三、合并果子
使用小根堆,先添加所有数据,在每次删除两个最小的,添加这两者的和,重复n-1次
#include <bits/stdc++.h>
using namespace std;
const int N = 1e4+5;
int A[N];
struct Compare {
bool operator()(int a, int b) {
return a > b;
}
};
int main (){
int n;
cin>>n;
for(int i = 1 ;i<=n;i++){
cin>>A[i];
}
priority_queue<int, vector<int>, Compare> c;
for(int i = 1 ;i<=n;i++){
c.push(A[i]);
}
int m1,m2;
long long count = 0;
for(int i = 1 ;i<n;i++){
m1=c.top();
c.pop();
m2=c.top();
c.pop();
c.push(m1+m2);
count+=(m1+m2);
}
cout<<count<<endl;
}
四、约瑟夫问题
#include <bits/stdc++.h>
using namespace std;
int main() {
int n, m;
cin >> n >> m;
list<int> l;
for (int i = 1; i <= n; i++) {
l.push_back(i);
}
int count = 0;
auto it = l.begin();
while (!l.empty()) {
count++;
if (count == m) {
cout << *it << " ";
it = l.erase(it);
count = 0;
if (l.empty()) break;
if (it == l.end()) {
it = l.begin();
}
} else {
it++;
if (it == l.end()) {
it = l.begin();
}
}
}
return 0;
}
五、仰望奶牛
使用栈,找到阶段性最高点,再让入栈元素一个个出栈
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5+5;
int H[N];
int main(){
int n;
cin>>n;
stack<int> st;
vector<int> result(n+1, 0);
for (int i = 1; i <= n; i++) {
cin >> H[i];
}
for (int i = n ; i >= 1; i--){
while (!st.empty() && H[st.top()] <= H[i]) {
st.pop();
}
if(!st.empty()){
result[i] = st.top();
}
st.push(i);
}
for (int i = 1; i <= n; i++) {
cout << result[i] << endl;
}
return 0;
}
六、国旗
可以观察到,输入元素的起始点是递增的
使用st表,找到一定距离内,一个人最多跑到哪(下一个人的起点),再检测是否符合自己的奔袭区间
#include <bits/stdc++.h>
using namespace std;
using namespace std;
int n, m, res[200005];
struct soldier {
int id, l, r;
} s[420005];
int cmp(soldier a, soldier b)
{
return a.l < b.l;
}
int go[420005][20];
void pre()
{
for(int i = 1, p = i; i <= 2 * n; i++) {
while(p <= 2 * n && s[p].l <= s[i].r)
p++;
int pos = p - 1;
go[i][0] = pos;
}
for(int i = 1; i < 20; i++) {
for(int j = 1; j <= 2 * n; j++) {
go[j][i] = go[go[j][i - 1]][i - 1];
}
}
}
void search(int k)
{
int lmt = s[k].l + m, ans = 1, p = k;
for(int i = 19; i >= 0; i--) {
if(go[k][i] != 0 && s[go[k][i]].r < lmt) {
ans += (1 << i);
k = go[k][i];
}
}
res[s[p].id] = ans + 1;
}
int main()
{
cin >> n >> m;
for(int i = 1; i <= n; i++) {
cin >> s[i].l >> s[i].r;
if(s[i].r < s[i].l)
s[i].r += m;
s[i].id = i;
}
sort(s + 1, s + 1 + n, cmp);
for(int i = 1; i <= n; i++) {
s[i + n] = s[i];
s[i + n].l = s[i].l + m;
s[i + n].r = s[i].r + m;
}
pre();
for(int i = 1; i <= n; i++)
search(i);
for(int i = 1; i <= n; i++)
cout << res[i] << " ";
return 0;
}