zoukankan      html  css  js  c++  java
  • SPOJ

    题意:给你2e5个矮人,编号1~N。有2e5个操作:操作1 读取x,y,交换编号为x,y的矮人。操作2 读取AB 判断编号为A,A+1····B的矮人是否连续(不必有序)。

    题解:首先用pos[i]保存矮人i的位置,交换就用swap(pos[l],pos[r])来模拟。然后发现条件等价于(pos[l],pos[r])的区间满足最大值为r,最小值为l且区间内人数等于r-l+1即可。所以直接维护区间最大最小值。用change(1,p,x)来更新p处的矮人编号,并pushup。

    坑:最开始ask忘写return。想用一个pair<int,int> query 一次性返回大于小于号,会tle。最坑的是忘记判端pos[l]pos[r]的大小,导致RE。

    ac代码:

    #define _CRT_SECURE_NO_WARNINGS
    #include<iostream>
    #include<stdio.h>
    #include<algorithm>
    using namespace std;
    const int maxnn = 200010;
    int m, n, pos[200010];
    pair<int, int> ans;
    struct node {
        int l, r, maxn, minn;
    }tree[800010];
    inline void push_up(int x) {
        tree[x].maxn = max(tree[x << 1].maxn, tree[x << 1 | 1].maxn);
        tree[x].minn = min(tree[x << 1].minn, tree[x << 1 | 1].minn);
    };
    
    
    inline void build(int x, int l, int r) {
        tree[x].l = l; tree[x].r = r;
        //tree[x].maxn = l; tree[x].minn = maxnn;
        if (l == r) { tree[x].maxn = tree[x].minn = l; return; }
    
            int mid = (l+ r) >> 1;
            build(x << 1, l, mid);
            build(x << 1 | 1, mid + 1, r);
            push_up(x);
    
    };
    inline void change(int x, int p,int d) {
        int L=tree[x].l,R=tree[x].r;
        if (L == R) {
            tree[x].maxn = tree[x].minn = d; return;
        }
    
            int mid = (L + R) >> 1;
            if (p <= mid)change(x << 1,p, d);
            else change(x << 1 | 1,p, d);
            push_up(x);
    
    }
    
    inline int askmx(int x,int l,int r) {
        int L = tree[x].l, R = tree[x].r;
        if (L==l&&r == R)    return tree[x].maxn;
        
            int mid = (L + R) >> 1;
            if (r <= mid)return askmx(x << 1, l, r);
            else if (l > mid)return askmx(x << 1 | 1, l, r);
            else return max(askmx(x << 1, l, mid), askmx(x << 1 | 1, mid + 1, r));
    }
    inline int askmn(int x, int l,    int r) {
        int L = tree[x].l, R = tree[x].r;
        if (L == l&&r == R) return tree[x].minn;
    
            int mid = L + R >> 1;
            if (r <= mid)return askmn(x << 1, l, r);
            else if (l > mid)return askmn(x << 1 | 1, l, r);
            else return min(askmn(x << 1, l, mid), askmn(x << 1 | 1, mid + 1, r));
            
    }
    int main() {
        int n, q;
        cin >> n >> q;
        build(1, 1, n);
        for (int i = 1; i <= n; i++)pos[i] = i;
        
        for (int i = 1; i <= q; i++) {
            int x; int l; int r;
            scanf("%d", &x);
            scanf("%d%d", &l, &r);
            
            if (x == 1) {    
                swap(pos[l], pos[r]);
                change(1, pos[l], l);
                change(1, pos[r], r);
            }
            else {
                        
                //ans= query(1, pos[l], pos[r]);
                if (l > r)swap(l, r);
                int rr = pos[r]; 
                int ll = pos[l];
                if (ll > rr)swap(ll, rr);
                if (askmn(1, ll, rr)==l&&  askmx(1, ll, rr)==r&&rr-ll == r-l)puts("YES");
                else puts("NO");
    
            }
        }
    }
    成功的路并不拥挤,因为大部分人都在颓(笑)
  • 相关阅读:
    VS2005 中关于“LC.EXE已退出,代码为 1”的错误解决方法。
    由于目标机器积极拒绝,无法连接。
    What is Android?
    利用批处理文件和任务计划实现Oracle数据库的自动备份
    就差了一点点....
    由Login.aspx引发编译器错误的解决方法
    都是补丁惹的祸...
    终于结束了
    GIS当然可以很酷
    rar.exe命令行参数与示例
  • 原文地址:https://www.cnblogs.com/SuuT/p/8572978.html
Copyright © 2011-2022 走看看