排队 (白雪公主与n个小矮人)
题目描述
【问题描述】
在七山七海之外的一个小村庄,白雪公主与N个矮人住在一起,所有时间都花在吃和玩League of Legend游戏。白雪公主决心终结这样的生活,所以为他们举办了体育课。 在每节课开始时,矮人必须按他们的身高站队。假定矮人们有高度1,2,...,N(每个人高度互不相同)。然而,由于不健康的生活方式,矮人的智力有所恶化,所以他们没有能力依照自己的高度排序。
因此,白雪公主发出以下形式命令帮助他们:
1 X Y:X和Y位置的矮人互换位置。
2 A B:询问高度为A,A+1,..., B的矮人(不一定是按照这个顺序)是否已形成了当前队列的连续子序列。
帮助矮人按照白雪公主的指示行动,并回答她的问题。
【输入格式】
输入的第一行包含两个正整数N和M,分别表示矮人的数量和白雪公主的命令数,2≤N≤200,000,2≤M≤200,000。
第二行包含N个用空格隔开的从1到N的正整数,每个数只出现一次,代表矮人的初始排列。
接下来的M行包含白雪公主的命令,形式为“1 X Y”(1≤X,Y≤N,X≠Y)或“2 A B”(1≤A≤B≤N)。
【输出格式】
对于每个命令2输出“YES”或“NO”。
solution
解法1:按高度建树,每次找区间最大 最小值
解法2:按位置直接建树,每次找的时候,随便在询问区间找一个数
左右延伸判断 (我没打...)
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 using namespace std; 5 const int N=200006; 6 void swap(int &x,int &y){x^=y;y^=x;x^=y;} 7 int maxn(int a,int b){return a>b?a:b;} 8 int minn(int a,int b){return a<b?a:b;} 9 10 int n,m,u; 11 int v[N],pos[N]; 12 13 struct son 14 { 15 int max,min; 16 }; 17 son a[N*5]; 18 void pushup(int x) 19 { 20 a[x].min=minn(a[x<<1].min,a[x<<1|1].min); 21 a[x].max=maxn(a[x<<1].max,a[x<<1|1].max); 22 } 23 void build(int l,int r,int x) 24 { 25 if(l==r) 26 { 27 a[x].min=a[x].max=pos[l]; 28 return ; 29 } 30 int mid=(l+r)>>1; 31 build(l,mid,x<<1); 32 build(mid+1,r,x<<1|1); 33 pushup(x); 34 } 35 void changedian(int pos,int val,int l,int r,int x) 36 { 37 if(l==r) 38 { 39 a[x].min=a[x].max=val; 40 return ; 41 } 42 int mid=(l+r)>>1; 43 if(pos<=mid) 44 changedian(pos,val,l,mid,x<<1); 45 else 46 changedian(pos,val,mid+1,r,x<<1|1); 47 pushup(x); 48 } 49 int qqmax(int L,int R,int l,int r,int x) 50 { 51 if(L<=l&&r<=R) 52 return a[x].max; 53 int mid=(l+r)>>1; 54 int ans=0; 55 if(L<=mid) 56 ans=maxn(ans,qqmax(L,R,l,mid,x<<1)); 57 if(mid<R) 58 ans=maxn(ans,qqmax(L,R,mid+1,r,x<<1|1)); 59 return ans; 60 } 61 int qqmin(int L,int R,int l,int r,int x) 62 { 63 if(L<=l&&r<=R) 64 return a[x].min; 65 int mid=(l+r)>>1; 66 int ans=0x7fffffff; 67 if(L<=mid) 68 ans=minn(ans,qqmin(L,R,l,mid,x<<1)); 69 if(mid<R) 70 ans=minn(ans,qqmin(L,R,mid+1,r,x<<1|1)); 71 return ans; 72 } 73 int main(){ 74 75 scanf("%d%d",&n,&m); 76 for(int i=1;i<=n;++i) 77 { 78 scanf("%d",&u); 79 pos[u]=i;v[i]=u; 80 } 81 build(1,n,1); 82 while(m--) 83 { 84 int kk,x,y; 85 scanf("%d%d%d",&kk,&x,&y); 86 if(kk==1) 87 { 88 changedian(v[x],y,1,n,1); 89 changedian(v[y],x,1,n,1); 90 swap(v[x],v[y]); 91 } 92 else 93 { 94 int maxl=qqmax(x,y,1,n,1); 95 int minl=qqmin(x,y,1,n,1); 96 if(maxl-minl==y-x) 97 printf("YES\n"); 98 else 99 printf("NO\n"); 100 } 101 } 102 //while(1); 103 return 0; 104 }