ARC080E
倒着考虑
每次拿出的第一个必须是奇数位置,第二个必须是偶数位置。每次删数都不能跨过已被删去的位置。
事实上只要开个堆维护一下区间就行了。但是众所周知我zz,所以我写的线段树
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int M = 1000001;
int n,m,k,a[M],d[2][M],mr[M],tag[M],R[M],w[2][M];
void update(int now)
{
if(d[0][now*2]>d[0][now*2+1])
{
d[0][now]=d[0][now*2+1];
w[0][now]=w[0][now*2+1];
}
else
{
d[0][now]=d[0][now*2];
w[0][now]=w[0][now*2];
}
if(d[1][now*2]>d[1][now*2+1])
{
d[1][now]=d[1][now*2+1];
w[1][now]=w[1][now*2+1];
}
else
{
d[1][now]=d[1][now*2];
w[1][now]=w[1][now*2];
}
}
void built(int now,int l,int r)
{
if(l==r)
{
int t=l&1;
d[!t][now]=0x3f3f3f3f;
d[t][now]=a[l];
w[t][now]=l;
mr[now]=n;
return ;
}
int mid=(l+r)>>1,t=0;
built(now*2,l,mid); built(now*2+1,mid+1,r);
update(now);
mr[now]=n;
}
void pd(int now)
{
if(tag[now])
{
swap(d[0][now*2],d[1][now*2]);
swap(d[0][now*2+1],d[1][now*2+1]);
swap(w[0][now*2],w[1][now*2]);
swap(w[0][now*2+1],w[1][now*2+1]);
tag[now*2]^=1; tag[now*2+1]^=1;
tag[now]=0;
}
mr[now*2]=min(mr[now*2],mr[now]);
mr[now*2+1]=min(mr[now*2+1],mr[now]);
}
int ask1(int now,int l,int r)
{
if(l==r) {R[l]=mr[now]; d[1][now]=0x3f3f3f3f; return l;}
int mid=(l+r)>>1,k; pd(now);
if(d[1][now]==d[1][now*2]) k=ask1(now*2,l,mid);
else k=ask1(now*2+1,mid+1,r);
update(now);
return k;
}
int ask2(int now,int l,int r,int L,int R)
{
if(l>=L && r<=R) return w[0][now];
int mid=(l+r)>>1,g,k=0; pd(now);
if(L<=mid) k=ask2(now*2,l,mid,L,R);
if(R>mid)
{
g=ask2(now*2+1,mid+1,r,L,R);
if(a[g]<a[k]) k=g;
}
return k;
}
void mody2(int now,int l,int r,int L,int R,int x)
{
if(l>=L && r<=R)
{
if(x)
{
tag[now]^=1;
swap(d[0][now],d[1][now]);
swap(w[0][now],w[1][now]);
}
mr[now]=min(mr[now],R);
return ;
}
int mid=(l+r)>>1; pd(now);
if(L<=mid) mody2(now*2,l,mid,L,R,x);
if(R>mid) mody2(now*2+1,mid+1,r,L,R,x);
update(now);
}
void mody1(int now,int l,int r,int x)
{
if(l==r)
{
d[0][now]=0x3f3f3f3f;
w[0][now]=0;
return ;
}
int mid=(l+r)>>1; pd(now);
if(x<=mid) mody1(now*2,l,mid,x);
else mody1(now*2+1,mid+1,r,x);
update(now);
}
int main()
{
scanf("%d",&n); a[0]=0x3f3f3f3f;
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
built(1,1,n);
for(int i=1;i<=n/2;i++)
{
int k=ask1(1,1,n);
printf("%d ",a[k]);
int g=ask2(1,1,n,k+1,R[k]);
printf("%d ",a[g]);
mody1(1,1,n,g);
if(g-k>1)mody2(1,1,n,k+1,g-1,1);
if(k!=1)mody2(1,1,n,1,k-1,0);
}
}
ARC080E的更多相关文章
- Atcoder arc080E Young Maids(线段树+优先队列)
给出一个n排列,每次可以选择相邻的两个数字放在新的排列首部,问最后形成的新的排列字典序最小是? 考虑新排列的第一个数字,则应是下标为奇数的最小数,下标不妨设为i.第二个数字应该下标大于i且为偶数的最小 ...
- 在$CF$水题の记录
CF1158C CF1163E update after CF1173 很好,我!expert!掉rating了!! 成为pupil指日可待== 下次要记得合理安排时间== ps.一道题都没写的\(a ...
随机推荐
- spring注解开发:bean的作用域与懒加载
1.bean的作用域 1.新建一个maven工程,添加如下依赖 <dependency> <groupId>org.springframework</groupId> ...
- 使用systemctl管理服务
系统服务,开机不需要登录就能运行的程序(相当于开机自启)/usr/lib/systemd/system 用户服务,需要登录后才能运行的程序/usr/lib/systemd/user 目录下又存在两种类 ...
- Python中sys模块
Python的sys模块提供访问解释器使用或维护的变量,和与解释器进行交互的函数.通俗来讲,sys模块负责程序与python解释器的交互,提供了一系列的函数和变量,用于操控python运行时的环境. ...
- docker--build自己的image
通过container commit成image [root@localhost docker_test]# docker container commit #可以简写成docker commit a ...
- 60.Median of Two Sorted Arrays(两个排序数组的中位数)
Level: Hard 题目描述: There are two sorted arrays nums1 and nums2 of size m and n respectively. Find t ...
- microtime函数用法
/** * microtime函数 * 返回:如果参数为空,则返回字符串 "微妙部分(单位:秒) 秒",字符串的两部分都是以"秒"为单位返回的 * 如果参数为 ...
- shell位置参数处理举例
- shutdown - 关闭系统
总览 SYNOPSIS /sbin/shutdown [-t sec] [-arkhncfF] time [warning-message] 描述 DESCRIPTION shutdown 以一种安全 ...
- Java 基础 - 自动装箱,valueOf装箱,new -->使用 == 和 equals比较
总结 关于equals 比较 记住:equals方法比较的是真正的值 两个包装类比较,比较的是包装的基本数据类型的值 基本数据类型和包装类型比较时,会先把基本数据类型包装后再比较 (但是因为equa ...
- 牛客挑战赛33 F 淳平的形态形成场(无向图计数,EGF,多项式求逆)
传送门: 淳平的形态形成场 题解: 把a排序后,直接统计答案恰好为a[i]并不好做,可以统计答案>a[i]的方案数,设为\(f[i]\). 即不存在一个联通块,所有的权值都<=a[i]. ...