优美序列(sequence)
问题描述
Lxy养了N头奶牛,他把N头奶牛用1..N编号,第i头奶牛编号为i。为了让奶牛多产奶,每天早上他都会让奶牛们排成一排做早操。奶牛们是随机排列的。在奶牛排列中,如果一段区间[L,R]中的数从小到大排列后是连续的,他认为这段区间是优美的。比如奶牛排列为:(3, 1, 7, 5, 6, 4, 2),区间[3,6]是优美的,它包含4,5,6,7连续的四个数,而区间[1,3] 是不优美的。Lxy的问题是:对于给定的一个区间[L,R](1<=L<=R<=N), 他想知道,包含区间[L,R]的最短优美区间,比如区间[1,3]的最短优美区间是[1,7]。
输入
第一行为一个整数N,表示奶牛的个数。
第二行为1到N的一个排列,表示奶牛的队伍。
第三行为一个整数M,表示有M个询问。
后面有M行,每行有两个整数L,R表示询问区间。
输出
输出为M行,每行两个整数,表示包含询问区间的最短优美区间。
输入输出样例
样例1
input
7
3 1 7 5 6 4 2
3
3 6
7 7
1 3
output
3 6
7 7
1 7
样例2
input
10
2 1 4 3 5 6 7 10 8 9
5
2 3
3 7
4 7
4 8
7 8
output
1 4
3 7
3 7
3 10
7 10
数据范围
15%的数据满足: 1 <=N,M <= 15;
50%的数据满足:1 <=N,M <= 1000。
100%的数据满足:1 <=N,M <= 100000。
解析
为了给出题人留面子,不让他被骂出个题只有一种解法而且只有满分解法,我先给个80分做法。
预处理一个数组pos[i],表示数i在原数组的位置(第几个数)。
在询问区间内找一个最小值和最大值,作为新的l和r,新的l和r作为一个询问区间,在pos数组里找一个最小值和最大值,他们再作为新的l和r,形成询问区间,在原数组寻找最小值和最大值,并再次重复刚才的操作……
上述过程可能很无脑很中二,然而这就是模拟题意找出答案的过程。
最大值最小值用st表预处理,一共四个st表,比线段树好写……
那么……
正解是分治,像归并排序那样。
不断求[l,mid] [mid+1,r]的优美序列,直到分成[mid,mid+1]
可以证明是正确的。
事实上分治做的熟练的人可能一眼秒这道题。
代码
80pts
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
template<class T>
void read(T &res)
{
res = 0;
T f = 1;
char cc = getchar();
while(cc < '0' || cc > '9')
{
if(cc == '-') f = -1;
cc = getchar();
}
while(cc >= '0' && cc <= '9')
{
res = res * 10 + cc - '0';
cc = getchar();
}
res *= f;
}
const int maxn = 1e5 + 5;
int n,m;
int seqmin[maxn][50];
int posmin[maxn][50];
int seqmax[maxn][50];
int posmax[maxn][50];
int ansl,ansr;
void init()
{
for(int j=1;(1<<j) <= n;j++)
{
for(int i=0;i+(1<<j)-1 <= n;i++)
{
seqmax[i][j] = max(seqmax[i][j-1],seqmax[i+(1<<(j-1))][j-1]); // 1
seqmin[i][j] = min(seqmin[i][j-1],seqmin[i+(1<<(j-1))][j-1]); // 2
posmax[i][j] = max(posmax[i][j-1],posmax[i+(1<<(j-1))][j-1]); // 3
posmin[i][j] = min(posmin[i][j-1],posmin[i+(1<<(j-1))][j-1]); // 4
}
}
}
int query(int l,int r,int ju)
{
int t = int(log((double)(r - l + 1)) / log(2.0));
if(ju == 1)
return max(seqmax[l][t],seqmax[r-(1<<t)+1][t]);
if(ju == 2)
return min(seqmin[l][t],seqmin[r-(1<<t)+1][t]);
if(ju == 3)
return max(posmax[l][t],posmax[r-(1<<t)+1][t]);
if(ju == 4)
return min(posmin[l][t],posmin[r-(1<<t)+1][t]);
}
void change(int inl,int inr)
{
int templ,tempr,endl,endr;
templ = query(inl,inr,2);
tempr = query(inl,inr,1);
endl = query(templ,tempr,4);
endr = query(templ,tempr,3);
if(endl == inl && endr == inr)
{
ansl = endl;
ansr = endr;
return;
}
else
change(endl,endr);
}
int main()
{
freopen("sequence.in","r",stdin);
freopen("sequence.out","w",stdout);
read(n);
for(int i=1;i<=n;i++)
read(seqmin[i][0]),seqmax[i][0] = seqmin[i][0];
for(int i=1;i<=n;i++)
posmax[seqmin[i][0]][0] = i,posmin[seqmin[i][0]][0] = i;
init();
read(m);
while(m--)
{
int l,r;
read(l);read(r);
change(l,r);
printf("%d %d\n",ansl,ansr);
}
return 0;
}
100pts
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=100005;
#define pb push_back
#define lc (o<<1)
#define mid (l+r>>1)
#define rc ((o<<1)|1)
struct ask{
int L,num;
bool operator <(const ask &u)const{
return L<u.L;
}
};
vector<ask> g[N];
multiset<ask> s;
multiset<ask> :: iterator it;
int n,a[N],p[N],mx[N*4],pos[N*4],Q;
int le,ri,w,al[N],ar[N],M,P,tag[N*4];
inline void mt(int o){
mx[o]=max(mx[lc],mx[rc]);
pos[o]=(mx[rc]==mx[o]?pos[rc]:pos[lc]);
}
inline void work(int o,int der){ tag[o]+=der,mx[o]+=der;}
inline void pd(int o){ if(tag[o]) work(lc,tag[o]),work(rc,tag[o]),tag[o]=0;}
void build(int o,int l,int r){
mx[o]=r,pos[o]=r;
if(l==r) return;
build(lc,l,mid),build(rc,mid+1,r);
}
void update(int o,int l,int r){
if(l>=le&&r<=ri){ work(o,w); return;}
pd(o);
if(le<=mid) update(lc,l,mid);
if(ri>mid) update(rc,mid+1,r);
mt(o);
}
void query(int o,int l,int r){
if(l>=le&&r<=ri){ if(mx[o]>M) M=mx[o],P=pos[o]; return;}
pd(o);
if(ri>mid) query(rc,mid+1,r);
if(le<=mid) query(lc,l,mid);
}
inline bool can(int cc){
le=1,ri=it->L,M=P=0;
query(1,1,n);
if(M==cc){ al[it->num]=P,ar[it->num]=cc; return 1;}
return 0;
}
inline void solve(){
build(1,1,n),w=1;
ask inf=(ask){233333,0};
for(int i=1;i<=n;i++){
for(ask x:g[i]) s.insert(x);
ri=p[a[i]-1],le=1;
if(ri&&ri<i) update(1,1,n);
ri=p[a[i]+1],le=1;
if(ri&&ri<i) update(1,1,n);
for(;s.size();s.erase(it)){
it=--s.lower_bound(inf);
if(!can(i)) break;
}
}
}
int main(){
freopen("sequence.in","r",stdin);
freopen("sequence.out","w",stdout);
scanf("%d",&n);
for(int i=1;i<=n;i++) {
scanf("%d",&a[i]);
p[a[i]]=i;
};
scanf("%d",&Q);
for(int i=1,l,r;i<=Q;i++){
scanf("%d %d",&l,&r);
g[r].pb((ask){l,i});
}
solve();
for(int i=1;i<=Q;i++) printf("%d %d\n",al[i],ar[i]);
return 0;
}
优美序列(sequence)的更多相关文章
- [JZOJ6279] 2019.8.5【NOIP提高组A】优美序列
题目 题目大意 给你一个排列以及若干区间,对于每个区间,问包含它的最小的优美序列的区间. 所谓优美序列,即将权值排序后能够得到连续的排列. 思考历程 优美序列显然满足这个条件:\(mx-mn=r-l\ ...
- Oracle新表使用序列(sequence)作为插入值,初始值不是第一个,oraclesequence
Oracle新表使用序列(sequence)作为插入值,初始值不是第一个,oraclesequence 使用oracle11g插入数据时遇到这样一个问题: 1 --创建测试表-- 2 CREATE T ...
- Oracle序列(Sequence)创建、使用、修改、删除
Oracle对象课程:序列(Sequence)创建.使用.修改.删除,序列(Sequence)是用来生成连续的整数数据的对象.序列常常用来作为主键中增长列,序列中的可以升序生成,也可以降序生成.创建序 ...
- 序列sequence中的cache问题
Oracle中序列Sequence的创建语法如下: CREATE SEQUENCE [ schema. ] sequence [ { INCREMENT BY | START WITH } integ ...
- oracle数据库--序列(sequence)
一个问题: 在某张表中,存在一个id列(整数),我们希望在添加记录的时候,该列从1开始,自动的增长,怎么处理? 解决方式:oracle是利用"序列"(sequence)来完成的. ...
- Oracle数据库中序列(SEQUENCE)的用法详解
Oracle数据库中序列(SEQUENCE)的用法详解 在Oracle数据库中,序列的用途是生成表的主键值,可以在插入语句中引用,也可以通过查询检查当前值,或使序列增至下一个值.本文我们主要介绍了 ...
- Oracle 序列(sequence)
序列(sequence) 是Oracle提供的用于生成一系列唯一数字的数据库对象.它会自动生成顺序递增或者递减的序列号,以实现自动提供唯一的主键值.序列可以在多用户并发环境中使用,并且可以为所有用户生 ...
- oracle 序列sequence
查询所有的序列: select 'create sequence '||sequence_name|| ' minvalue '||min_value|| ' maxvalue '||max_valu ...
- 序列(SEQUENCE)
序列(SEQUENCE)是序列号生成器,可以为表中的行自动生成序列号,产生一组等间隔的数值(类型为数字).其主要的用途是生成表的主键值,可以在插入语句中引用,也可以通过查询检查当前值,或使序列增至下一 ...
随机推荐
- thinkphp5在Linux下Nginx配置问题解决
首先tp5的访问目录指向到webroot/public文件夹中. thinkphp的url访问:http://serverName/index.php(或者其它应用入口文件)/模块/控制器/操作/[参 ...
- IIS 字符串过长
jquery.datatable.js---弹窗要用极速模式 <?xml version="1.0" encoding="utf-8"?><c ...
- 【学习】数据聚合和分组运算【groupby】
分组键可以有多种方式,且类型不必相同 列表或数组, 某长度与待分组的轴一样 表示DataFrame某个列名的值 字典或Series,给出待分组轴上的值与分组名之间的对应关系 函数用于处理轴索引或索引中 ...
- PG数据库——视图
视图(View)是从一个或多个表(或视图)导出的表.视图与表(有时为与视图区别,也称表为基本表——Base Table)不同,视图是一个虚表,即视图所对应的数据不进行实际存储,数据库中只存储视图的定义 ...
- MogoDB(6)--mongoDB高可用和4.0特性
5.1.MongoDB 用户管理 1.用户管理1.1.添加用户为 testdb 添加 tom 用户 use testdb db.createUser({user:"tom",pwd ...
- nginx的命令
- LNMP 支持路由重写
server { listen 80; #listen [::]:80; server_name www.xxx.com; index i ...
- Win10远程桌面 出现 身份验证错误,要求的函数不受支持,这可能是由于CredSSP加密Oracle修正 解决方法
升级至win10 最新版本18362,远程桌面连接Window Server时报错信息如下: 出现身份验证错误,要求的函数不正确,这可能是由于CredSSP加密Oracle修正. 解决方法: 运行 g ...
- 使用pip安装包提示TLS证书错误解决办法
最近有在使用pip安装python包的时候,总会出现以下类似的错误: Could not fetch URL https://pypi.python.org/simple/pytest-xdist/: ...
- 常用Macro
[enable_if] SFINAE是英文Substitution failure is not an error的缩写. 这句话什么意思呢?当调用模板函数时编译器会根据传入参数推导最合适的模板函数, ...