080E 思维+优先队列维护

题意:初始q为空,给出排列p,每次取p中两个相邻的元素插入到q的开头,问q能得到的最小字典序为?
n<=2e5.
开头尽量小,假设最后一次取出的元素位置为[i,j].
则ij之间有偶数个元素,i前面有偶数个元素,j类似.i,j奇偶性相反.
i必须在某个奇数位置上,j必须在某个偶数位置上,RMQ维护奇/偶位置上的最小值
每次取出一个v1以后,查询v1后面的奇/偶性相反的最小值.
线段被分为三段[1,i),(i,j),(j,n] 把子线段加入到优先队列中(key为该线段左端点开始偶数位置中的最小值) O(nlogn).

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll inf=0x3f3f3f3f;
const int N=2e5+20;
int mn[2][N][30],n,a[2][N],pos[N];
void init(int v)
{
    for(int i=0;i<n;i++)
        mn[v][i][0]=a[v][i];
    for(int j=1;(1<<j)<=n;j++)
        for(int i=0;(i+(1<<j)-1)<n;i++)
            mn[v][i][j]=min(mn[v][i][j-1],mn[v][i+(1<<(j-1))][j-1]);
}
int rmq(int l,int r,int v)
{
    int k=0;
    while((1<<(k+1))<=r-l+1)
        k++;
    return min(mn[v][l][k],mn[v][r-(1<<k)+1][k]);
}
struct node{
    int x,l,r;
    bool operator < (const node &t)const{
        return x>t.x;
    }
};
int main()
{
    int x;
    while(cin>>n)
    {
        for(int i=0;i<n;i++)
        {
            scanf("%d",&x);
            pos[x]=i;
            a[i&1][i]=x;
            a[(i&1)^1][i]=inf;
        }
        init(0),init(1);
        priority_queue<node> q;
        x=rmq(0,n-1,0);
        q.push({x,0,n-1});
        while(!q.empty())
        {
            node x=q.top();
            q.pop();
            int v1=x.x,v2=rmq(pos[x.x]+1,x.r,(pos[x.x]&1)^1);
            printf("%d %d ",v1,v2);
            v1=pos[v1],v2=pos[v2];
            if(x.l!=v1)
                q.push({rmq(x.l,v1-1,x.l&1),x.l,v1-1});
            if(v1+1!=v2)
                q.push({rmq(v1+1,v2-1,(v1+1)&1),v1+1,v2-1});
            if(v2!=x.r)
                q.push({rmq(v2+1,x.r,(v2+1)&1),v2+1,x.r});
        }
        printf("\n");
    }
    return 0;

} 
时间: 2024-11-05 09:09:30

080E 思维+优先队列维护的相关文章

Codeforces Round #451 (Div. 2)【A,B,C,D,E】【C题:模拟 D题:尺取+贪心 E题:思维+优先队列维护最值】

特判最后一位即可 1 #include<bits/stdc++.h> 2 3 using namespace std; 4 #define int long long 5 6 signed main(){ 7 int n;cin>>n;int t=n%10; 8 if(t==0) cout<<n; 9 else if(t>5) { 10 cout<<(n+10-t); 11 } 12 else { 13 cout<<(n-t); 14 }

CF446B DZY Loves Modification 【思维/优先队列】By cellur925

题目传送门 题目大意:给一个 \(n*m\) 的矩阵,并进行 \(k\) 次操作,每次操作将矩阵的一行或一列的所有元素的值减 \(p\) ,得到的分数为这次修改之前这一列/一行的元素和,求分数最大值. 我开始的意识流想法是用一个优先队列维护,先把所有元素插入,然后\(k\)次每次取出堆顶,减去乘\(p\)的什么东西,再塞回队中.但是...行与列是会互相影响的鸭,那么怎么搞呢?然后就不会了hh. 正解是努力打破了行与列之间的相互影响,把行与列分开计算.我们考虑行与列是怎么互相影响的:选择\(i\)

bzoj1150: [CTSC2007]数据备份Backup--贪心+优先队列维护堆

题目大意:将k对点两两相连,求最小长度 易证得,最优方案中,相连的办公楼一定是取相邻的比取不相邻的要更优 然后就可以用贪心来做这道题了.. 之前向CZL大神学习了用堆来贪心的做法orz 大概思路就是将初始所有的线段放进堆里 每次取最短的线段进行连接,且ans+=a[i] 取完后删除当前线段,与相邻的两条线段,同时再插入新边,权值为a[pre]+a[next]-a[now] 其作用与最大流中的反向弧有点像,下一次若取到这条边,即ans+=a[pre]+a[next]-a[now] 很明显a[now

[luoguP2672] 推销员(贪心 + 树状数组 + 优先队列)

传送门 贪心...蒟蒻证明不会... 每一次找最大的即可,找出一次最大的,数列会分为左右两边,左边用stl优先队列维护,右边用树状数组维护.. (线段树超时了....) 代码 #include <queue> #include <cstdio> #include <iostream> #define N 100001 #define ls now << 1 #define rs now << 1 | 1 #define max(x, y) (p[

UVA 11997 K Smallest Sums 优先队列 多路合并

vjudge 上题目链接:UVA 11997 题意很简单,就是从 k 个数组(每个数组均包含 k 个正整数)中各取出一个整数相加(所以可以得到 kk 个结果),输出前 k 小的和. 这时训练指南上的一道题,这道题的简化版其实在 15 年的广东省省赛出现过,当时是以送分题的形式出现的,可我还是没能做出来,归根到底还是看书不够,接触的题型不够多. *************************************************************大白书上的讲解开始*******

uva 501 - Black Box(优先队列)

题目链接:uva 501 - Black Box 题目大意:有一个集合,给定元素进入集合的顺序,现在有Q次查询,给定每次查询在第几个元素进入集合后,对于每i次查询,输出集合中第i小的数. 解题思路:用两个优先队列维护,队列a优先出值大的,队列b优先出值小的,在第i次询问前,保证a队列中有i-1个元素元素,并且抱枕都比b中的小,然后每次询问输出b队列的首元素,并且将它放到a队列中. #include <cstdio> #include <cstring> #include <q

URAL1306-Sequence Median(优先队列)

1306. Sequence Median Time limit: 1.0 second Memory limit: 1 MB Language limit: C, C++, Pascal Given a sequence of N nonnegative integers. Let's define the median of such sequence. If N is odd the median is the element with stands in the middle of th

Atcoder arc080E Young Maids(线段树+优先队列)

给出一个n排列,每次可以选择相邻的两个数字放在新的排列首部,问最后形成的新的排列字典序最小是? 考虑新排列的第一个数字,则应是下标为奇数的最小数,下标不妨设为i.第二个数字应该下标大于i且为偶数的最小数,不妨设为j. 那么这样就将[1,n]新分割成了三个区间[1,i-1],[i+1,j-1],[j+1,n]. 用线段树实现查询操作.用优先队列维护区间的最优值. 时间复杂度O(nlogn). # include <cstdio> # include <cstring> # inclu

hdu5336 多校联合第四场1010 模拟+bfs优先队列

http://acm.hdu.edu.cn/showproblem.php?pid=5336 Problem Description XYZ is playing an interesting game called "drops". It is played on a r?c grid. Each grid cell is either empty, or occupied by a waterdrop. Each waterdrop has a property "siz