题目描述
在七山七海之外的一个小村庄,白雪公主与 NNN 个矮人住在一起,所有时间都花在吃、和玩League of Legend游戏。白雪公主决心终结这样的生活,所以为他们举办了体育课。
在每节课开始的,矮人必须按他们的身高站队。假定矮人们有高度 1,2,⋯ ,N1,2,\cdots,N1,2,⋯,N(每个高度一次)。然而,由于不健康的生活方式,矮人的智力有所恶化,所以他们没有能力依照自己的高度排序。
因此,白雪公主发出以下形式命令帮助他们:
1 X Y1XY1 X Y 在 XXX 和 YYY 位置的矮人必须互换位置。
她还通过发出以下形式的查询检查了他们的排序情况:
2 A B2AB2 A B 高度为 A,A+1,⋯ ,BA,A+1,\cdots,BA,A+1,⋯,B的矮人(不一定是按照这个顺序)是否已形成了当前队列的连续子序列?
帮助呆矮人按照白雪公主的指示行动,并回答她的问题。
输入格式
输入的第一行包含两个正整数 NNN 和 MMM ,分别表示矮人的数量和白雪公主的命令数,2≤N≤200000,2≤M≤200000 2 \le N \le 200000, 2 \le M \le 200000 2≤N≤200000,2≤M≤200000
下面的行中包含 NNN 个用空格分离的从 111 到 NNN 的正整数,每个数只出现一次,代表矮人的初始排列。
接下来的 MMM 行包含白雪公主的一个单一的命令,如问题陈述中所描述的那样,形式为 1 X Y1XY1 X Y ,1≤X,Y≤N,X!=Y1 \le X,Y \le N,X!=Y1≤X,Y≤N,X!=Y ,或 2 A B2AB2 A B, 1≤A≤B≤N1 \le A \le B \le N 1≤A≤B≤N
输出格式
每行输出必须包含为每一个类型2查询的应答,“YES”或“NO”。
样例
样例输入
7 7
4 7 3 5 1 2 6
2 1 7
1 3 7
2 4 6
2 4 7
2 1 4
1 1 4
2 1 4
样例输出
YES
NO
YES
NO
YES
数据范围与提示
50%的数据 对于所有的类型2查询,B-A≤50恒成立
来源
coci2013 7th
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdio>
#define N 200005
using namespace std;
int n,a[N],pos[N],m;
struct segment
{
int l,r,mx_pos,mn_pos;
}t[N<<2];
void build(int p,int l,int r){
t[p].l=l;t[p].r=r;
if(l==r)return ;
int mid=(l+r)>>1;
build(p*2,l,mid);build(p*2+1,mid+1,r);
}
void change(int p,int pos,int val){
if(t[p].l==t[p].r){
t[p].mx_pos=val;
t[p].mn_pos=val;
return ;
}
int mid=(t[p].l+t[p].r)>>1;
if(pos<=mid)change(p*2,pos,val);
if(pos>mid)change(p*2+1,pos,val);
t[p].mx_pos=max(t[p*2].mx_pos,t[p*2+1].mx_pos);
t[p].mn_pos=min(t[p*2].mn_pos,t[p*2+1].mn_pos);
}
struct Ans
{
int mx,mn;
};
Ans ask(int p,int l,int r){
if(t[p].l>=l&&t[p].r<=r){
return Ans{t[p].mx_pos,t[p].mn_pos};
}
int mid=(t[p].l+t[p].r)>>1;
Ans ans;ans.mx=0;ans.mn=200005+100;Ans son_ans;
if(l<=mid){son_ans=ask(p*2,l,r);ans.mx=max(ans.mx,son_ans.mx);ans.mn=min(ans.mn,son_ans.mn);}
if(r>mid){son_ans=ask(p*2+1,l,r);ans.mx=max(ans.mx,son_ans.mx);ans.mn=min(ans.mn,son_ans.mn);}
return ans;
}
int main()
{
scanf("%d%d",&n,&m);
build(1,1,n);
for(int i=1;i<=n;++i){
scanf("%d",&a[i]);
change(1,a[i],i);
}
for(int i=1;i<=m;++i){
int op,x,y;scanf("%d%d%d",&op,&x,&y);
if(op==1){
int x_num=a[x],y_num=a[y];
change(1,x_num,y);change(1,y_num,x);
a[x]=y_num;a[y]=x_num;
}else{
if(x>y)swap(x,y);
Ans ans=ask(1,x,y);
if(ans.mx-ans.mn>y-x)printf("NO\n");
else printf("YES\n");
}
}
return 0;
}