排队 (白雪公主与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 }
解法1

 

posted @ 2017-08-05 11:56  A_LEAF  阅读(232)  评论(0编辑  收藏  举报