5.19NOI模拟赛1

A.
B.1-n的全排列,两个操作:1、(1,a,b)交换位置a和位置b上的数。2、(2,a,b)查询a.a+1…b是否可以组成一个连续序列,可以不按照升序,例如:a.a+2,a+1,在(2,a,a+2)时,ans=YES.(n<=200000)
其实可以算一眼线段树吧= =
线段树区间[a,b]维护mn,mx,[a,b]在序列里最左边最右边的值。单点修改,查询。此题丧病卡常数。话说第一次遇见卡常数的题。。。不过想想,以前写的seg都是代码少,常数大的。。。好像确实该改改了。。。(tle第一次才55= =

#include<iostream>
#include<cstdio>
#include<cstdlib>
#define N 200005
#define pa pair<int,int>
#define mp make_pair
#define inf 0x7fffffff
using namespace std;
struct seg{
    int l,r,mx,mn;
}t[N*4];
int v[N],pos[N],n,m,mn,mx;
void build(int k,int l,int r){
    t[k].l=l;t[k].r=r;
    if(l==r){
        t[k].mx=pos[l];
        t[k].mn=pos[l];
        return;
    }
    int mid=(l+r)>>1;
    build(k<<1,l,mid);build(k<<1|1,mid+1,r);
    t[k].mx=max(t[k<<1].mx,t[k<<1|1].mx);
    t[k].mn=min(t[k<<1].mn,t[k<<1|1].mn);
}
void modify(int k,int a,int x){//pos[a]->x
    if(t[k].r<a||a<t[k].l) return;
    if(t[k].l==a&&t[k].r==a){
        t[k].mx=x;t[k].mn=x;
        return;
    }
    int mid=(t[k].l+t[k].r)>>1;
    if(a<=mid) modify(k<<1,a,x);
    if(a>mid) modify(k<<1|1,a,x);
    t[k].mx=max(t[k<<1].mx,t[k<<1|1].mx);
    t[k].mn=min(t[k<<1].mn,t[k<<1|1].mn);
}
void query(int k,int a,int b){
    if(t[k].r<a||b<t[k].l) return;
    if(a<=t[k].l&&t[k].r<=b) {
        mx=max(mx,t[k].mx);
        mn=min(mn,t[k].mn);
        return;
    }
    int mid=(t[k].l+t[k].r)>>1;
    if(b<=mid) {query(k<<1,a,b);return;}
    if(a>mid) {query(k<<1|1,a,b);return;}
    query(k<<1,a,b);query(k<<1|1,a,b);
}
int main(){
    freopen("in.txt","r",stdin);
    freopen("out.txt","w",stdout);
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)                  //pos[x]=i 身高为x位于i 
        scanf("%d",&v[i]),pos[v[i]]=i;     //v[x]=i 位于x身高i 
    build(1,1,n);
    for(int i=1;i<=m;i++){
        int o,a,b;
        scanf("%d%d%d",&o,&a,&b);
        if(o==1){
            modify(1,v[a],pos[v[b]]); 
            modify(1,v[b],pos[v[a]]);           
            swap(pos[v[a]],pos[v[b]]);
            swap(v[a],v[b]);
        }
        if(o==2){
            mx=0;mn=inf;
            query(1,a,b);
            if(mx-mn==b-a) printf("YES\n");
            else printf("NO\n");
        }
    }
    return 0;
}

C.

发布了87 篇原创文章 · 获赞 7 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/yxr0105/article/details/51453722
今日推荐